import { useEffect, useMemo, useState } from 'react';

import {
  isMemberLogStreamUiEnabled,
  MemberLogStreamSection,
} from '@features/member-log-stream/renderer';
// import { MemberWorkSyncStatusPanel } from '@features/member-work-sync/renderer';
import { Button } from '@renderer/components/ui/button';
import { Dialog, DialogContent, DialogFooter, DialogHeader } from '@renderer/components/ui/dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@renderer/components/ui/tabs';
import { useMemberStats } from '@renderer/hooks/useMemberStats';
import { useStore } from '@renderer/store';
import { selectMemberMessagesForTeamMember } from '@renderer/store/slices/teamSlice';
import { isOpenCodeRelaunchActionable } from '@renderer/utils/memberHelpers';
import {
  buildMemberLaunchDiagnosticsPayload,
  getMemberLaunchDiagnosticsErrorMessage,
  hasMemberLaunchDiagnosticsDetails,
  hasMemberLaunchDiagnosticsError,
} from '@renderer/utils/memberLaunchDiagnostics';
import {
  getRuntimeMemorySourceLabel,
  resolveMemberRuntimeSummary,
} from '@renderer/utils/memberRuntimeSummary';
import { isDisplayableCurrentTask } from '@renderer/utils/teamTaskDisplayState';
import { isLeadMember } from '@shared/utils/leadDetection';
import { isTeamTaskFinishedForDependency } from '@shared/utils/teamTaskState';
import {
  BarChart3,
  FileText,
  ListPlus,
  Loader2,
  MessageSquare,
  RotateCcw,
  UserMinus,
} from 'lucide-react';

import { buildMemberActivityEntries } from './memberActivityEntries';
import { MemberDetailHeader } from './MemberDetailHeader';
import { MemberDetailStats } from './MemberDetailStats';
import { type MemberActivityFilter, type MemberDetailTab } from './memberDetailTypes';
import { MemberLaunchDiagnosticsButton } from './MemberLaunchDiagnosticsButton';
import { MemberLogsTab } from './MemberLogsTab';
import { MemberMessagesTab } from './MemberMessagesTab';
import { MemberStatsTab } from './MemberStatsTab';
import { MemberTasksTab } from './MemberTasksTab';

import type { TeamLaunchParams } from '@renderer/store/slices/teamSlice';
import type {
  LeadActivityState,
  MemberSpawnStatusEntry,
  ResolvedTeamMember,
  TeamAgentRuntimeEntry,
  TeamTaskWithKanban,
} from '@shared/types';

const OPENCODE_NO_RUNTIME_EVIDENCE_MESSAGE =
  'No OpenCode runtime session was recorded. Relaunch this teammate to start a fresh OpenCode session.';
const OPENCODE_BOOTSTRAP_STALLED_MESSAGE =
  'OpenCode process is alive, but bootstrap did not confirm. Relaunch this teammate to start a fresh OpenCode session.';

function hasOpenCodeRuntimeEvidence(runtimeEntry: TeamAgentRuntimeEntry | undefined): boolean {
  const hasPid =
    typeof runtimeEntry?.pid === 'number' &&
    Number.isFinite(runtimeEntry.pid) &&
    runtimeEntry.pid > 0;
  const hasRuntimePid =
    typeof runtimeEntry?.runtimePid === 'number' &&
    Number.isFinite(runtimeEntry.runtimePid) &&
    runtimeEntry.runtimePid > 0;
  const hasRuntimeSessionId =
    typeof runtimeEntry?.runtimeSessionId === 'string' &&
    runtimeEntry.runtimeSessionId.trim().length > 0;
  const hasRuntimeLiveness =
    runtimeEntry?.livenessKind === 'runtime_process' ||
    runtimeEntry?.livenessKind === 'runtime_process_candidate' ||
    runtimeEntry?.livenessKind === 'permission_blocked';
  return Boolean(hasPid || hasRuntimePid || hasRuntimeSessionId || hasRuntimeLiveness);
}

function isOpenCodeNoRuntimeEvidenceFailure(
  member: ResolvedTeamMember,
  spawnEntry: MemberSpawnStatusEntry | undefined,
  runtimeEntry: TeamAgentRuntimeEntry | undefined
): boolean {
  const failed = spawnEntry?.launchState === 'failed_to_start' || spawnEntry?.status === 'error';
  return member.providerId === 'opencode' && failed && !hasOpenCodeRuntimeEvidence(runtimeEntry);
}

interface MemberDetailDialogProps {
  open: boolean;
  member: ResolvedTeamMember | null;
  teamName: string;
  members: ResolvedTeamMember[];
  tasks: TeamTaskWithKanban[];
  initialTab?: MemberDetailTab;
  initialActivityFilter?: MemberActivityFilter;
  isTeamAlive?: boolean;
  isTeamProvisioning?: boolean;
  isLaunchSettling?: boolean;
  leadActivity?: LeadActivityState;
  spawnEntry?: MemberSpawnStatusEntry;
  runtimeEntry?: TeamAgentRuntimeEntry;
  runtimeRunId?: string | null;
  launchParams?: TeamLaunchParams;
  onClose: () => void;
  onSendMessage: () => void;
  onAssignTask: () => void;
  onTaskClick: (task: TeamTaskWithKanban) => void;
  onRemoveMember?: () => void;
  onRestartMember?: (memberName: string) => Promise<void> | void;
  onUpdateRole?: (memberName: string, role: string | undefined) => Promise<void> | void;
  updatingRole?: boolean;
  onViewMemberChanges?: (memberName: string, filePath?: string) => void;
}

export const MemberDetailDialog = ({
  open,
  member,
  teamName,
  members,
  tasks,
  initialTab = 'tasks',
  initialActivityFilter = 'all',
  isTeamAlive,
  isTeamProvisioning,
  isLaunchSettling,
  leadActivity,
  spawnEntry,
  runtimeEntry,
  runtimeRunId,
  launchParams,
  onClose,
  onSendMessage,
  onAssignTask,
  onTaskClick,
  onRemoveMember,
  onRestartMember,
  onUpdateRole,
  updatingRole,
  onViewMemberChanges,
}: MemberDetailDialogProps): React.JSX.Element | null => {
  const memberTasks = useMemo(
    () => (member ? tasks.filter((t) => t.owner === member.name) : []),
    [tasks, member]
  );
  const memberMessages = useStore((state) =>
    selectMemberMessagesForTeamMember(state, teamName, member?.name ?? null)
  );
  const memberActivityCount = useMemo(() => {
    if (!member) {
      return 0;
    }
    return buildMemberActivityEntries({
      teamName,
      memberName: member.name,
      members,
      tasks,
      messages: memberMessages,
    }).length;
  }, [member, memberMessages, members, tasks, teamName]);

  const inProgressTasks = useMemo(
    () => memberTasks.filter(isDisplayableCurrentTask).length,
    [memberTasks]
  );
  const currentTaskCandidate = useMemo(
    () =>
      member?.currentTaskId
        ? (tasks.find((task) => task.id === member.currentTaskId) ?? null)
        : null,
    [member?.currentTaskId, tasks]
  );
  const displayableCurrentTask = isDisplayableCurrentTask(currentTaskCandidate)
    ? currentTaskCandidate
    : null;

  const completedTasks = useMemo(
    () => memberTasks.filter(isTeamTaskFinishedForDependency).length,
    [memberTasks]
  );

  const [activeTab, setActiveTab] = useState<MemberDetailTab>(initialTab);
  const [restarting, setRestarting] = useState(false);
  const [restartError, setRestartError] = useState<string | null>(null);
  const [showLegacyLogsFallback, setShowLegacyLogsFallback] = useState(false);

  const runtimeSummary = useMemo(
    () =>
      member
        ? resolveMemberRuntimeSummary(member, launchParams, spawnEntry, runtimeEntry)
        : undefined,
    [launchParams, member, runtimeEntry, spawnEntry]
  );
  const memorySourceLabel = getRuntimeMemorySourceLabel(runtimeEntry);
  const openCodeRelaunchActionable = member
    ? isOpenCodeRelaunchActionable({ member, spawnEntry, runtimeEntry })
    : false;
  const restartInFlight =
    !openCodeRelaunchActionable &&
    (spawnEntry?.launchState === 'starting' ||
      spawnEntry?.launchState === 'runtime_pending_bootstrap' ||
      spawnEntry?.launchState === 'runtime_pending_permission');
  const launchDiagnosticsPayload = useMemo(
    () =>
      member
        ? buildMemberLaunchDiagnosticsPayload({
            teamName,
            runId: runtimeRunId,
            memberName: member.name,
            spawnEntry,
            runtimeEntry,
          })
        : null,
    [member, runtimeEntry, runtimeRunId, spawnEntry, teamName]
  );
  const showCopyDiagnostics =
    launchDiagnosticsPayload != null &&
    hasMemberLaunchDiagnosticsError(launchDiagnosticsPayload) &&
    hasMemberLaunchDiagnosticsDetails(launchDiagnosticsPayload);
  const launchErrorMessage = launchDiagnosticsPayload
    ? getMemberLaunchDiagnosticsErrorMessage(launchDiagnosticsPayload)
    : undefined;
  const openCodeBootstrapStalled =
    member?.providerId === 'opencode' && spawnEntry?.bootstrapStalled === true;
  const openCodeNoRuntimeEvidence = member
    ? isOpenCodeNoRuntimeEvidenceFailure(member, spawnEntry, runtimeEntry)
    : false;
  const effectiveLaunchErrorMessage = openCodeNoRuntimeEvidence
    ? OPENCODE_NO_RUNTIME_EVIDENCE_MESSAGE
    : launchErrorMessage;
  const effectiveLaunchInfoMessage = openCodeBootstrapStalled
    ? OPENCODE_BOOTSTRAP_STALLED_MESSAGE
    : undefined;
  const isOpenCodeMember = member?.providerId === 'opencode';
  const restartButtonLabel = isOpenCodeMember ? 'Relaunch OpenCode' : 'Restart';
  const hasLiveRestartContext = isTeamAlive === true || isTeamProvisioning === true;
  const canControlledOpenCodeRelaunch =
    member == null
      ? false
      : isOpenCodeMember && !member.removedAt && !isLeadMember(member) && hasLiveRestartContext;
  const canRestartFromDialog =
    member == null
      ? false
      : Boolean(onRestartMember) &&
        !isLeadMember(member) &&
        hasLiveRestartContext &&
        (runtimeEntry?.restartable !== false || canControlledOpenCodeRelaunch);

  useEffect(() => {
    if (!open || !member) {
      return;
    }
    setActiveTab(initialTab);
    setRestartError(null);
    setRestarting(false);
    setShowLegacyLogsFallback(false);
  }, [initialTab, member, open]);

  const {
    stats: memberStats,
    loading: statsLoading,
    error: statsError,
  } = useMemberStats(teamName, member?.name ?? null);

  const totalTokens = memberStats ? memberStats.inputTokens + memberStats.outputTokens : null;
  const memberLogStreamEnabled = isMemberLogStreamUiEnabled();

  if (!member) return null;

  return (
    <Dialog open={open} onOpenChange={(nextOpen) => !nextOpen && onClose()}>
      <DialogContent className="min-w-0 sm:max-w-4xl">
        <div className="flex items-start gap-4">
          <DialogHeader className="shrink-0">
            <MemberDetailHeader
              member={
                member.currentTaskId && !displayableCurrentTask
                  ? { ...member, currentTaskId: null }
                  : member
              }
              runtimeSummary={runtimeSummary}
              isTeamAlive={isTeamAlive}
              isTeamProvisioning={isTeamProvisioning}
              leadActivity={isLeadMember(member) ? leadActivity : undefined}
              spawnStatus={spawnEntry?.status}
              spawnLaunchState={spawnEntry?.launchState}
              spawnLivenessSource={spawnEntry?.livenessSource}
              spawnRuntimeAlive={spawnEntry?.runtimeAlive}
              spawnBootstrapConfirmed={spawnEntry?.bootstrapConfirmed}
              spawnBootstrapStalled={spawnEntry?.bootstrapStalled}
              spawnFirstSpawnAcceptedAt={spawnEntry?.firstSpawnAcceptedAt}
              spawnUpdatedAt={spawnEntry?.updatedAt}
              runtimeEntry={runtimeEntry}
              isLaunchSettling={isLaunchSettling}
              onUpdateRole={
                onUpdateRole ? (newRole) => onUpdateRole(member.name, newRole) : undefined
              }
              updatingRole={updatingRole}
            />
          </DialogHeader>

          <MemberDetailStats
            totalTasks={memberTasks.length}
            inProgressTasks={inProgressTasks}
            completedTasks={completedTasks}
            activityCount={memberActivityCount}
            totalTokens={totalTokens}
            statsLoading={statsLoading}
            statsComputedAt={memberStats?.computedAt}
            onTabChange={setActiveTab}
          />
        </div>

        <Tabs
          value={activeTab}
          onValueChange={(v) => setActiveTab(v as MemberDetailTab)}
          className="min-w-0 overflow-hidden"
        >
          <TabsList className="w-full">
            <TabsTrigger value="tasks" className="flex-1 gap-1.5">
              Tasks
              {memberTasks.length > 0 && (
                <span className="rounded-full bg-[var(--color-surface)] px-1.5 text-[10px]">
                  {memberTasks.length}
                </span>
              )}
            </TabsTrigger>
            <TabsTrigger value="activity" className="flex-1 gap-1.5">
              Activity
              {memberActivityCount > 0 && (
                <span className="rounded-full bg-[var(--color-surface)] px-1.5 text-[10px]">
                  {memberActivityCount}
                </span>
              )}
            </TabsTrigger>
            <TabsTrigger value="stats" className="flex-1 gap-1.5">
              <BarChart3 size={12} />
              Stats
            </TabsTrigger>
            <TabsTrigger value="logs" className="flex-1 gap-1.5">
              <FileText size={12} />
              Logs
            </TabsTrigger>
          </TabsList>
          <TabsContent value="tasks">
            <div className="space-y-3">
              {/*
              <MemberWorkSyncStatusPanel
                teamName={teamName}
                memberName={member.name}
                enabled={open && !member.removedAt}
              />
              */}
              <MemberTasksTab tasks={memberTasks} onTaskClick={onTaskClick} />
            </div>
          </TabsContent>
          <TabsContent value="activity">
            <MemberMessagesTab
              teamName={teamName}
              memberName={member.name}
              members={members}
              tasks={tasks}
              initialFilter={initialActivityFilter}
              onTaskClick={onTaskClick}
            />
          </TabsContent>
          <TabsContent value="stats">
            <MemberStatsTab
              teamName={teamName}
              memberName={member.name}
              prefetchedStats={memberStats}
              prefetchedLoading={statsLoading}
              prefetchedError={statsError}
              onFileClick={(filePath) => onViewMemberChanges?.(member.name, filePath)}
              onShowAllFiles={() => onViewMemberChanges?.(member.name)}
            />
          </TabsContent>
          <TabsContent value="logs" className="min-w-0 overflow-hidden">
            {memberLogStreamEnabled ? (
              <div className="space-y-4">
                <MemberLogStreamSection
                  teamName={teamName}
                  member={member}
                  enabled={open && activeTab === 'logs'}
                  onInitialLoadErrorChange={setShowLegacyLogsFallback}
                />
                {showLegacyLogsFallback ? (
                  <div className="rounded-md border border-[var(--color-border)] p-3">
                    <div className="mb-3 text-xs font-semibold uppercase text-[var(--color-text-muted)]">
                      Legacy Logs Fallback
                    </div>
                    <MemberLogsTab teamName={teamName} memberName={member.name} />
                  </div>
                ) : null}
              </div>
            ) : (
              <MemberLogsTab teamName={teamName} memberName={member.name} />
            )}
          </TabsContent>
        </Tabs>

        <DialogFooter>
          {restartError ? (
            <div className="mr-auto text-xs text-red-400">{restartError}</div>
          ) : effectiveLaunchErrorMessage ? (
            <div className="mr-auto flex min-w-0 items-center gap-2 text-xs text-red-400">
              <span className="min-w-0 truncate" title={effectiveLaunchErrorMessage}>
                {effectiveLaunchErrorMessage}
              </span>
              {launchDiagnosticsPayload && showCopyDiagnostics ? (
                <MemberLaunchDiagnosticsButton
                  payload={launchDiagnosticsPayload}
                  label="Copy diagnostics"
                  className="h-auto shrink-0 gap-1.5 px-2 py-1 text-red-300 hover:bg-red-500/10 hover:text-red-200"
                />
              ) : null}
            </div>
          ) : effectiveLaunchInfoMessage ? (
            <div className="mr-auto flex min-w-0 items-center gap-2 text-xs text-amber-300">
              <span className="min-w-0 truncate" title={effectiveLaunchInfoMessage}>
                {effectiveLaunchInfoMessage}
              </span>
            </div>
          ) : runtimeEntry?.pid ? (
            <div className="mr-auto text-xs text-[var(--color-text-muted)]">
              PID {runtimeEntry.pid}
              {memorySourceLabel ? ` · ${memorySourceLabel}` : ''}
            </div>
          ) : (
            <div className="mr-auto" />
          )}
          {member.removedAt ? (
            <span className="text-xs text-[var(--color-text-muted)]">
              Removed {new Date(member.removedAt).toLocaleDateString()}
            </span>
          ) : (
            <>
              {canRestartFromDialog && (
                <Button
                  variant="outline"
                  size="sm"
                  className="gap-1.5"
                  disabled={restarting || restartInFlight}
                  onClick={async () => {
                    setRestartError(null);
                    setRestarting(true);
                    try {
                      if (!onRestartMember) return;
                      await onRestartMember(member.name);
                    } catch (error) {
                      setRestartError(
                        error instanceof Error ? error.message : 'Failed to restart member'
                      );
                    } finally {
                      setRestarting(false);
                    }
                  }}
                >
                  {restarting ? (
                    <Loader2 size={14} className="animate-spin" />
                  ) : (
                    <RotateCcw size={14} />
                  )}
                  {restartButtonLabel}
                </Button>
              )}
              <Button variant="outline" size="sm" className="gap-1.5" onClick={onSendMessage}>
                <MessageSquare size={14} />
                Send Message
              </Button>
              <Button variant="outline" size="sm" className="gap-1.5" onClick={onAssignTask}>
                <ListPlus size={14} />
                Assign Task
              </Button>
              {onRemoveMember && !isLeadMember(member) && (
                <Button
                  variant="outline"
                  size="sm"
                  className="gap-1.5 text-red-400 hover:bg-red-500/10 hover:text-red-300"
                  onClick={onRemoveMember}
                >
                  <UserMinus size={14} />
                  Remove
                </Button>
              )}
            </>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};
