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

import { useAppTranslation } from '@features/localization/renderer';
import { Badge } from '@renderer/components/ui/badge';
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@renderer/components/ui/hover-card';
import {
  getTeamColorSet,
  getThemedBadge,
  getThemedBorder,
  getThemedText,
} from '@renderer/constants/teamColors';
import { useTheme } from '@renderer/hooks/useTheme';
import { useStore } from '@renderer/store';
import {
  getCurrentProvisioningProgressForTeam,
  selectResolvedMemberForTeamName,
  selectTeamIsAliveForName,
  selectTeamMemberSnapshotsForName,
  selectTeamTasksForName,
} from '@renderer/store/slices/teamSlice';
import { formatAgentRole } from '@renderer/utils/formatAgentRole';
import {
  agentAvatarUrl,
  buildMemberAvatarMap,
  buildMemberLaunchPresentation,
  displayMemberName,
  shouldDisplayMemberCurrentTask,
} from '@renderer/utils/memberHelpers';
import {
  buildMemberLaunchDiagnosticsPayload,
  getMemberLaunchDiagnosticsErrorMessage,
  hasMemberLaunchDiagnosticsDetails,
  hasMemberLaunchDiagnosticsError,
} from '@renderer/utils/memberLaunchDiagnostics';
import { isDisplayableCurrentTask } from '@renderer/utils/teamTaskDisplayState';
import { isLeadMember } from '@shared/utils/leadDetection';
import { getTeamTaskWorkflowColumn } from '@shared/utils/teamTaskState';
import { ExternalLink } from 'lucide-react';
import { useShallow } from 'zustand/react/shallow';

import { getLaunchJoinMilestonesFromMembers, getLaunchJoinState } from '../provisioningSteps';

import { CurrentTaskIndicator } from './CurrentTaskIndicator';
import { MemberLaunchDiagnosticsButton } from './MemberLaunchDiagnosticsButton';
import { MemberPresenceDot } from './MemberPresenceDot';

import type { TeamTaskWithKanban } from '@shared/types';

interface MemberHoverCardProps {
  /** The member name to look up */
  name: string;
  /** Color key for the member */
  color?: string;
  /** Owning team context for store lookups. */
  teamName?: string;
  /** Called when user clicks on the current task */
  onOpenTask?: (task: TeamTaskWithKanban) => void;
  children: React.ReactNode;
}

/**
 * Wraps children in a HoverCard that mounts detailed member data only while open.
 */
export const MemberHoverCard = memo(function MemberHoverCard({
  name,
  color,
  teamName,
  onOpenTask,
  children,
}: MemberHoverCardProps): React.JSX.Element {
  const [open, setOpen] = useState(false);

  return (
    <HoverCard open={open} onOpenChange={setOpen} openDelay={300} closeDelay={200}>
      <HoverCardTrigger asChild>{children}</HoverCardTrigger>
      {open ? (
        <MemberHoverCardContent
          name={name}
          color={color}
          teamName={teamName}
          onOpenTask={onOpenTask}
        />
      ) : null}
    </HoverCard>
  );
});

interface MemberHoverCardContentProps {
  name: string;
  color?: string;
  teamName?: string;
  onOpenTask?: (task: TeamTaskWithKanban) => void;
}

const MemberHoverCardContent = ({
  name,
  color,
  teamName,
  onOpenTask,
}: MemberHoverCardContentProps): React.JSX.Element | null => {
  const { t } = useAppTranslation('team');
  const { isLight } = useTheme();
  const effectiveTeamName = useStore((s) => teamName ?? s.selectedTeamName);
  const {
    member,
    teamMembers,
    tasks,
    isTeamAlive,
    progress,
    memberSpawnSnapshot,
    memberSpawnStatuses,
    spawnEntry,
    runtimeRunId,
    runtimeEntries,
    runtimeEntry,
    leadActivity,
  } = useStore(
    useShallow((s) => ({
      member: effectiveTeamName
        ? selectResolvedMemberForTeamName(s, effectiveTeamName, name)
        : null,
      teamMembers: effectiveTeamName ? selectTeamMemberSnapshotsForName(s, effectiveTeamName) : [],
      tasks: effectiveTeamName ? selectTeamTasksForName(s, effectiveTeamName) : [],
      isTeamAlive: effectiveTeamName ? selectTeamIsAliveForName(s, effectiveTeamName) : undefined,
      progress: effectiveTeamName
        ? getCurrentProvisioningProgressForTeam(s, effectiveTeamName)
        : null,
      memberSpawnSnapshot: effectiveTeamName
        ? s.memberSpawnSnapshotsByTeam[effectiveTeamName]
        : undefined,
      memberSpawnStatuses: effectiveTeamName
        ? s.memberSpawnStatusesByTeam[effectiveTeamName]
        : undefined,
      spawnEntry: effectiveTeamName
        ? s.memberSpawnStatusesByTeam[effectiveTeamName]?.[name]
        : undefined,
      runtimeRunId: effectiveTeamName
        ? s.teamAgentRuntimeByTeam?.[effectiveTeamName]?.runId
        : undefined,
      runtimeEntries: effectiveTeamName
        ? s.teamAgentRuntimeByTeam?.[effectiveTeamName]?.members
        : undefined,
      runtimeEntry: effectiveTeamName
        ? s.teamAgentRuntimeByTeam?.[effectiveTeamName]?.members[name]
        : undefined,
      leadActivity: effectiveTeamName ? s.leadActivityByTeam[effectiveTeamName] : undefined,
    }))
  );
  const openMemberProfile = useStore((s) => s.openMemberProfile);
  const avatarMap = useMemo(() => buildMemberAvatarMap(teamMembers), [teamMembers]);

  if (!member) {
    return null;
  }

  const launchJoinMilestones = getLaunchJoinMilestonesFromMembers({
    members: teamMembers,
    memberSpawnStatuses,
    memberSpawnSnapshot,
    memberRuntimeEntries: runtimeEntries,
  });
  const isLaunchSettling =
    progress?.state === 'ready' && getLaunchJoinState(launchJoinMilestones).hasMembersStillJoining;
  const colors = getTeamColorSet(color ?? member.color ?? '');
  const roleLabel = formatAgentRole(member.role) ?? formatAgentRole(member.agentType);
  const currentTaskCandidate: TeamTaskWithKanban | null = member.currentTaskId
    ? (tasks.find((t) => t.id === member.currentTaskId) ?? null)
    : null;
  const currentTask =
    isDisplayableCurrentTask(currentTaskCandidate) &&
    shouldDisplayMemberCurrentTask({
      member,
      isTeamAlive,
      spawnStatus: spawnEntry?.status,
      spawnLaunchState: spawnEntry?.launchState,
      spawnRuntimeAlive: spawnEntry?.runtimeAlive,
      spawnEntry,
      runtimeEntry,
    })
      ? currentTaskCandidate
      : null;
  const presentationMember =
    member.currentTaskId && !currentTask
      ? {
          ...member,
          currentTaskId: null,
        }
      : member;
  const launchPresentation = buildMemberLaunchPresentation({
    member: presentationMember,
    spawnStatus: spawnEntry?.status,
    spawnLaunchState: spawnEntry?.launchState,
    spawnLivenessSource: spawnEntry?.livenessSource,
    spawnRuntimeAlive: spawnEntry?.runtimeAlive,
    spawnBootstrapConfirmed: spawnEntry?.bootstrapConfirmed,
    spawnBootstrapStalled: spawnEntry?.bootstrapStalled,
    spawnAgentToolAccepted: spawnEntry?.agentToolAccepted,
    spawnHardFailure: spawnEntry?.hardFailure,
    spawnHardFailureReason: spawnEntry?.hardFailureReason,
    spawnError: spawnEntry?.error,
    spawnRuntimeDiagnostic: spawnEntry?.runtimeDiagnostic,
    spawnLivenessKind: spawnEntry?.livenessKind,
    spawnRuntimeDiagnosticSeverity: spawnEntry?.runtimeDiagnosticSeverity,
    spawnFirstSpawnAcceptedAt: spawnEntry?.firstSpawnAcceptedAt,
    spawnUpdatedAt: spawnEntry?.updatedAt,
    runtimeEntry,
    runtimeAdvisory: member.runtimeAdvisory,
    isLaunchSettling,
    isTeamAlive,
    isTeamProvisioning: false,
    leadActivity: isLeadMember(member) ? leadActivity : undefined,
  });
  const presenceLabel = launchPresentation.presenceLabel;
  const launchVisualState = launchPresentation.launchVisualState;
  const launchStatusLabel = launchPresentation.launchStatusLabel;
  const dotClass = launchPresentation.dotClass;
  const runtimeAdvisoryLabel = launchPresentation.runtimeAdvisoryLabel;
  const runtimeAdvisoryTitle = launchPresentation.runtimeAdvisoryTitle;
  const runtimeAdvisoryTone = launchPresentation.runtimeAdvisoryTone;
  const badgeLabel =
    runtimeAdvisoryTone === 'error' && runtimeAdvisoryLabel
      ? runtimeAdvisoryLabel
      : launchVisualState === 'starting_stale' ||
          launchVisualState === 'bootstrap_stalled' ||
          launchVisualState === 'runtime_pending' ||
          launchVisualState === 'permission_pending' ||
          launchVisualState === 'shell_only' ||
          launchVisualState === 'runtime_candidate' ||
          launchVisualState === 'registered_only' ||
          launchVisualState === 'stale_runtime'
        ? (launchStatusLabel ?? presenceLabel)
        : presenceLabel;
  const launchDiagnosticsPayload = buildMemberLaunchDiagnosticsPayload({
    teamName: effectiveTeamName,
    runId: runtimeRunId ?? memberSpawnSnapshot?.runId ?? progress?.runId,
    memberName: member.name,
    member,
    spawnEntry,
    runtimeEntry,
  });
  const launchErrorMessage = getMemberLaunchDiagnosticsErrorMessage(launchDiagnosticsPayload);
  const showCopyDiagnostics =
    hasMemberLaunchDiagnosticsError(launchDiagnosticsPayload) &&
    hasMemberLaunchDiagnosticsDetails(launchDiagnosticsPayload);
  const reviewTaskCandidate: TeamTaskWithKanban | null = tasks
    ? (tasks.find(
        (task) =>
          task.reviewer === member.name &&
          task.id !== currentTask?.id &&
          getTeamTaskWorkflowColumn(task) === 'review'
      ) ?? null)
    : null;
  const reviewTask =
    reviewTaskCandidate &&
    shouldDisplayMemberCurrentTask({
      member,
      isTeamAlive,
      spawnStatus: spawnEntry?.status,
      spawnLaunchState: spawnEntry?.launchState,
      spawnRuntimeAlive: spawnEntry?.runtimeAlive,
      spawnEntry,
      runtimeEntry,
    })
      ? reviewTaskCandidate
      : null;

  return (
    <HoverCardContent side="top" align="start" sideOffset={8}>
      <div className="flex flex-col gap-2.5">
        {/* Header: avatar + name + presence */}
        <div className="flex items-center gap-3">
          <div className="relative shrink-0">
            <img
              src={avatarMap.get(member.name) ?? agentAvatarUrl(member.name, 64)}
              alt={member.name}
              className="size-10 rounded-full bg-[var(--color-surface-raised)]"
              loading="lazy"
            />
            <MemberPresenceDot className={`size-3 ${dotClass}`} label={badgeLabel} />
          </div>
          <div className="min-w-0 flex-1">
            <div className="flex items-center gap-1.5">
              <span
                className="truncate text-sm font-semibold"
                style={{ color: getThemedText(colors, isLight) }}
              >
                {displayMemberName(member.name)}
              </span>
              <Badge
                variant="secondary"
                className="shrink-0 px-1.5 py-0 text-[10px] font-normal leading-tight"
                title={runtimeAdvisoryTitle}
                style={{
                  backgroundColor:
                    runtimeAdvisoryTone === 'error'
                      ? 'rgba(239, 68, 68, 0.16)'
                      : getThemedBadge(colors, isLight),
                  color:
                    runtimeAdvisoryTone === 'error'
                      ? 'rgb(252, 165, 165)'
                      : getThemedText(colors, isLight),
                  border:
                    runtimeAdvisoryTone === 'error'
                      ? '1px solid rgba(248, 113, 113, 0.35)'
                      : `1px solid ${getThemedBorder(colors, isLight)}40`,
                }}
              >
                {badgeLabel}
              </Badge>
            </div>
            {roleLabel && (
              <span className="text-xs text-[var(--color-text-muted)]">{roleLabel}</span>
            )}
          </div>
        </div>

        {/* Current task */}
        {currentTask && (
          <div className="flex items-center gap-1 overflow-hidden rounded border border-[var(--color-border)] bg-[var(--color-surface)] px-2 py-1.5">
            <CurrentTaskIndicator
              task={currentTask}
              borderColor={colors.border}
              maxSubjectLength={28}
              activityLabel="working on"
              onOpenTask={onOpenTask ? () => onOpenTask(currentTask) : undefined}
            />
          </div>
        )}

        {/* Review task */}
        {reviewTask && (
          <div className="flex items-center gap-1 overflow-hidden rounded border border-[var(--color-border)] bg-[var(--color-surface)] px-2 py-1.5">
            <CurrentTaskIndicator
              task={reviewTask}
              borderColor={colors.border}
              maxSubjectLength={28}
              activityLabel="reviewing"
              onOpenTask={onOpenTask ? () => onOpenTask(reviewTask) : undefined}
            />
          </div>
        )}

        {launchErrorMessage ? (
          <div className="flex items-center gap-2 rounded border border-red-500/25 bg-red-500/10 px-2 py-1.5 text-xs text-red-300">
            <span className="min-w-0 flex-1 truncate" title={launchErrorMessage}>
              {launchErrorMessage}
            </span>
            {showCopyDiagnostics ? (
              <MemberLaunchDiagnosticsButton
                payload={launchDiagnosticsPayload}
                className="h-auto shrink-0 rounded px-1.5 py-1 text-red-300 hover:bg-red-500/10 hover:text-red-200"
              />
            ) : null}
          </div>
        ) : null}

        <div className="flex gap-1.5">
          <button
            type="button"
            className="flex flex-1 items-center justify-center gap-1.5 rounded border border-[var(--color-border)] px-3 py-1.5 text-xs text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-surface-raised)] hover:text-[var(--color-text)]"
            onClick={(e) => {
              e.stopPropagation();
              openMemberProfile(member.name);
            }}
          >
            <ExternalLink size={12} />
            {t('members.actions.openProfile')}
          </button>
        </div>
      </div>
    </HoverCardContent>
  );
};
