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

import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
import { EffortLevelSelector } from '@renderer/components/team/dialogs/EffortLevelSelector';
import {
  getProviderScopedTeamModelLabel,
  getTeamProviderLabel,
  TeamModelSelector,
} from '@renderer/components/team/dialogs/TeamModelSelector';
import { RoleSelect } from '@renderer/components/team/RoleSelect';
import { Button } from '@renderer/components/ui/button';
import { Input } from '@renderer/components/ui/input';
import { MentionableTextarea } from '@renderer/components/ui/MentionableTextarea';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { getTeamColorSet } from '@renderer/constants/teamColors';
import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence';
import { useFileListCacheWarmer } from '@renderer/hooks/useFileListCacheWarmer';
import { useTheme } from '@renderer/hooks/useTheme';
import { cn } from '@renderer/lib/utils';
import { reconcileChips, removeChipTokenFromText } from '@renderer/utils/chipUtils';
import { getMemberColorByName } from '@shared/constants/memberColors';
import { AlertTriangle, ChevronDown, ChevronRight, Info, RotateCcw, Trash2 } from 'lucide-react';

import type { MemberDraft } from './membersEditorTypes';
import type { InlineChip } from '@renderer/types/inlineChip';
import type { MentionSuggestion } from '@renderer/types/mention';
import type { EffortLevel, TeamProviderId } from '@shared/types';

interface MemberDraftRowProps {
  member: MemberDraft;
  index: number;
  resolvedColor?: string;
  nameError: string | null;
  onNameChange: (id: string, name: string) => void;
  onRoleChange: (id: string, roleSelection: string) => void;
  onCustomRoleChange: (id: string, customRole: string) => void;
  onRemove: (id: string) => void;
  showWorkflow?: boolean;
  onWorkflowChange?: (id: string, workflow: string) => void;
  onWorkflowChipsChange?: (id: string, chips: InlineChip[]) => void;
  onProviderChange: (id: string, providerId: TeamProviderId) => void;
  onModelChange: (id: string, model: string) => void;
  onEffortChange: (id: string, effort: string) => void;
  inheritedProviderId?: TeamProviderId;
  inheritedModel?: string;
  inheritedEffort?: EffortLevel;
  draftKeyPrefix?: string;
  projectPath?: string | null;
  mentionSuggestions?: MentionSuggestion[];
  taskSuggestions?: MentionSuggestion[];
  teamSuggestions?: MentionSuggestion[];
  lockProviderModel?: boolean;
  lockRole?: boolean;
  lockedRoleLabel?: string;
  lockIdentity?: boolean;
  identityLockReason?: string;
  forceInheritedModelSettings?: boolean;
  modelLockReason?: string;
  isRemoved?: boolean;
  onRestore?: (id: string) => void;
  hideActionButton?: boolean;
  warningText?: string | null;
  disableGeminiOption?: boolean;
  modelIssueText?: string | null;
}

export const MemberDraftRow = ({
  member,
  index,
  resolvedColor,
  nameError,
  onNameChange,
  onRoleChange,
  onCustomRoleChange,
  onRemove,
  showWorkflow = false,
  onWorkflowChange,
  onWorkflowChipsChange,
  onProviderChange,
  onModelChange,
  onEffortChange,
  inheritedProviderId = 'anthropic',
  inheritedModel = '',
  inheritedEffort,
  draftKeyPrefix,
  projectPath,
  mentionSuggestions = [],
  taskSuggestions,
  teamSuggestions,
  lockProviderModel = false,
  lockRole = false,
  lockedRoleLabel,
  lockIdentity = false,
  identityLockReason,
  forceInheritedModelSettings = false,
  modelLockReason,
  isRemoved = false,
  onRestore,
  hideActionButton = false,
  warningText,
  disableGeminiOption = false,
  modelIssueText,
}: MemberDraftRowProps): React.JSX.Element => {
  const { isLight } = useTheme();
  const memberColorSet = getTeamColorSet(
    resolvedColor ?? getMemberColorByName(member.name.trim() || `member-${index}`)
  );
  const [workflowExpanded, setWorkflowExpanded] = useState(false);
  const [modelExpanded, setModelExpanded] = useState(false);

  // Pre-warm file list cache when workflow section is expanded
  useFileListCacheWarmer(workflowExpanded && projectPath ? projectPath : null);

  const draftKey =
    draftKeyPrefix && (member.name.trim() || member.id)
      ? `${draftKeyPrefix}:workflow:${member.name.trim() || member.id}`
      : null;

  const workflowDraft = useDraftPersistence({
    key: draftKey ?? `workflow:${member.id}`,
    initialValue: member.workflow?.trim() ? member.workflow : undefined,
    enabled: !!draftKey,
  });

  const chips = useMemo(() => member.workflowChips ?? [], [member.workflowChips]);

  const handleWorkflowChange = useCallback(
    (v: string) => {
      const reconciled = reconcileChips(chips, v);
      if (reconciled.length !== chips.length) {
        onWorkflowChipsChange?.(member.id, reconciled);
      }
      workflowDraft.setValue(v);
      onWorkflowChange?.(member.id, v);
    },
    [member.id, chips, onWorkflowChange, onWorkflowChipsChange, workflowDraft]
  );

  const handleFileChipInsert = useCallback(
    (chip: InlineChip) => {
      onWorkflowChipsChange?.(member.id, [...chips, chip]);
    },
    [member.id, chips, onWorkflowChipsChange]
  );

  const handleChipRemove = useCallback(
    (chipId: string) => {
      const chip = chips.find((c) => c.id === chipId);
      if (!chip) return;
      const newChips = chips.filter((c) => c.id !== chipId);
      const newValue = removeChipTokenFromText(workflowDraft.value, chip);
      onWorkflowChipsChange?.(member.id, newChips);
      workflowDraft.setValue(newValue);
      onWorkflowChange?.(member.id, newValue);
    },
    [chips, member.id, onWorkflowChange, onWorkflowChipsChange, workflowDraft]
  );

  useEffect(() => {
    if (
      onWorkflowChange &&
      workflowDraft.value &&
      workflowDraft.value !== (member.workflow ?? '')
    ) {
      onWorkflowChange(member.id, workflowDraft.value);
    }
  }, [workflowDraft.value, member.id, member.workflow, onWorkflowChange]);

  const suggestionsExcludingSelf = mentionSuggestions.filter(
    (s) => s.name.toLowerCase() !== member.name.trim().toLowerCase()
  );
  const effectiveProviderId = forceInheritedModelSettings
    ? inheritedProviderId
    : (member.providerId ?? inheritedProviderId);
  const effectiveModel = forceInheritedModelSettings
    ? inheritedModel
    : (member.model ?? inheritedModel);
  const effectiveEffort = forceInheritedModelSettings
    ? inheritedEffort
    : (member.effort ?? inheritedEffort);
  const modelButtonLabelBase = effectiveModel?.trim()
    ? getProviderScopedTeamModelLabel(effectiveProviderId, effectiveModel.trim())
    : 'Default';
  const modelButtonLabel = forceInheritedModelSettings
    ? `${modelButtonLabelBase} (lead)`
    : modelButtonLabelBase;
  const modelButtonAriaLabel = `${getTeamProviderLabel(effectiveProviderId)} provider, ${modelButtonLabel}`;
  const modelTooltipText = forceInheritedModelSettings
    ? 'Provider, model, and effort are inherited from the lead while sync is enabled.'
    : modelLockReason;
  const hasModelIssue = Boolean(modelIssueText);

  return (
    <div
      className={`relative grid grid-cols-1 gap-2 rounded-md p-2 shadow-sm md:grid-cols-[minmax(0,1fr)_156px_auto] ${isRemoved ? 'opacity-55' : ''}`}
      style={{
        backgroundColor: isLight
          ? 'color-mix(in srgb, var(--color-surface-raised) 22%, white 78%)'
          : 'var(--color-surface-raised)',
        boxShadow: isLight ? '0 1px 2px rgba(15, 23, 42, 0.06)' : '0 1px 2px rgba(0, 0, 0, 0.28)',
      }}
    >
      <div
        className="absolute inset-y-0 left-0 w-1 rounded-l-md"
        style={{ backgroundColor: memberColorSet.border }}
        aria-hidden="true"
      />
      <div className="space-y-0.5">
        <Input
          className="h-8 text-xs"
          value={member.name}
          aria-label={`Member ${index + 1} name`}
          disabled={isRemoved || lockIdentity}
          onChange={(event) => onNameChange(member.id, event.target.value)}
          placeholder="member-name"
        />
        {nameError ? <p className="text-[10px] text-red-300">{nameError}</p> : null}
      </div>
      <div>
        {lockRole ? (
          <div className="flex h-8 items-center rounded-md border border-[var(--color-border)] bg-transparent px-3 text-xs text-[var(--color-text)] opacity-80">
            {lockedRoleLabel || member.customRole || member.roleSelection || 'No role'}
          </div>
        ) : (
          <RoleSelect
            value={member.roleSelection || '__none__'}
            disabled={isRemoved}
            onValueChange={(roleSelection) => onRoleChange(member.id, roleSelection)}
            customRole={member.customRole}
            onCustomRoleChange={(customRole) => onCustomRoleChange(member.id, customRole)}
            triggerClassName="h-8 text-xs"
            inputClassName="h-8 text-xs"
          />
        )}
      </div>
      <div className="space-y-1">
        <div className="flex flex-col gap-2 sm:flex-row sm:items-start">
          {showWorkflow && onWorkflowChange ? (
            <Button
              variant="outline"
              size="sm"
              className="relative h-8 shrink-0 gap-1"
              disabled={isRemoved}
              onClick={() => setWorkflowExpanded((prev) => !prev)}
            >
              {workflowExpanded ? (
                <ChevronDown className="size-3.5" />
              ) : (
                <ChevronRight className="size-3.5" />
              )}
              Workflow
              {!workflowExpanded && workflowDraft.value.trim() ? (
                <span className="absolute -right-1 -top-1 size-2 rounded-full bg-blue-500" />
              ) : null}
            </Button>
          ) : null}
          <div className="w-full min-w-0 space-y-1 sm:w-[150px] sm:min-w-[150px]">
            <Tooltip>
              <TooltipTrigger asChild>
                <span className="inline-flex w-full">
                  <Button
                    variant="outline"
                    size="sm"
                    className={cn(
                      'h-8 w-full justify-start gap-1 overflow-hidden text-left',
                      hasModelIssue &&
                        'border-red-500/50 bg-red-500/10 text-red-100 hover:border-red-400/60 hover:bg-red-500/15 hover:text-red-50'
                    )}
                    aria-label={modelButtonAriaLabel}
                    disabled={lockProviderModel || isRemoved}
                    onClick={() => setModelExpanded((prev) => !prev)}
                  >
                    {modelExpanded ? (
                      <ChevronDown className="size-3.5" />
                    ) : (
                      <ChevronRight className="size-3.5" />
                    )}
                    <ProviderBrandLogo
                      providerId={effectiveProviderId}
                      className="size-3.5 shrink-0"
                    />
                    <span className="min-w-0 flex-1 truncate">{modelButtonLabel}</span>
                    {hasModelIssue ? (
                      <AlertTriangle className="size-3.5 shrink-0 text-red-300" />
                    ) : null}
                  </Button>
                </span>
              </TooltipTrigger>
              {modelTooltipText || modelIssueText ? (
                <TooltipContent side="top" className="max-w-64 text-xs leading-relaxed">
                  {modelIssueText ? <p className="text-red-300">{modelIssueText}</p> : null}
                  {modelTooltipText ? (
                    <p className={modelIssueText ? 'mt-1 border-t border-white/10 pt-1' : ''}>
                      {modelTooltipText}
                    </p>
                  ) : null}
                </TooltipContent>
              ) : null}
            </Tooltip>
          </div>
          {hideActionButton ? null : isRemoved ? (
            <Button
              variant="outline"
              size="sm"
              className="size-8 shrink-0 px-0"
              aria-label={`Restore ${member.name || `member ${index + 1}`}`}
              title="Restore member"
              onClick={() => onRestore?.(member.id)}
            >
              <RotateCcw className="size-3.5" />
            </Button>
          ) : (
            <Button
              variant="outline"
              size="sm"
              className="size-8 shrink-0 border-red-500/40 px-0 text-red-300 hover:bg-red-500/10 hover:text-red-200"
              aria-label={`Remove ${member.name || `member ${index + 1}`}`}
              title="Remove member"
              onClick={() => onRemove(member.id)}
            >
              <Trash2 className="size-3.5" />
            </Button>
          )}
        </div>
        {isRemoved ? (
          <div className="pl-1 text-[11px] text-[var(--color-text-muted)]">Removed</div>
        ) : null}
      </div>
      {!isRemoved && warningText ? (
        <div className="md:col-span-3">
          <div className="bg-amber-500/8 ml-3 flex items-start gap-2 rounded-md border border-amber-500/25 px-3 py-2 text-[11px] leading-relaxed text-amber-200">
            <Info className="mt-0.5 size-3.5 shrink-0 text-amber-300" />
            <p>{warningText}</p>
          </div>
        </div>
      ) : null}
      {showWorkflow && onWorkflowChange && workflowExpanded ? (
        <div className="space-y-0.5 pl-3 md:col-span-3">
          <label
            htmlFor={`member-${member.id}-workflow`}
            className="block text-[10px] font-medium text-[var(--color-text-muted)]"
          >
            Workflow (optional)
          </label>
          <MentionableTextarea
            id={`member-${member.id}-workflow`}
            className="min-h-[80px] text-xs"
            minRows={3}
            maxRows={8}
            value={workflowDraft.value}
            onValueChange={handleWorkflowChange}
            suggestions={suggestionsExcludingSelf}
            taskSuggestions={taskSuggestions}
            teamSuggestions={teamSuggestions}
            chips={chips}
            onChipRemove={handleChipRemove}
            projectPath={projectPath ?? undefined}
            onFileChipInsert={handleFileChipInsert}
            placeholder="How this agent should behave, interact with others..."
            footerRight={
              workflowDraft.isSaved ? (
                <span className="text-[10px] text-[var(--color-text-muted)]">Saved</span>
              ) : null
            }
          />
        </div>
      ) : null}
      {modelExpanded && (
        <div className="space-y-2 pl-3 md:col-span-3">
          <TeamModelSelector
            providerId={effectiveProviderId}
            onProviderChange={(providerId) => {
              if (lockProviderModel) return;
              onProviderChange(member.id, providerId);
            }}
            value={effectiveModel ?? ''}
            onValueChange={(value) => {
              if (lockProviderModel) return;
              onModelChange(member.id, value);
            }}
            id={`member-${member.id}-model`}
            disableGeminiOption={disableGeminiOption}
            modelIssueReasonByValue={
              effectiveModel?.trim() ? { [effectiveModel.trim()]: modelIssueText } : undefined
            }
          />
          <EffortLevelSelector
            value={effectiveEffort ?? ''}
            onValueChange={(value) => {
              if (lockProviderModel) return;
              onEffortChange(member.id, value);
            }}
            id={`member-${member.id}-effort`}
          />
          {lockProviderModel && (
            <p className="text-[11px] text-amber-300">
              {modelLockReason ??
                'Provider, model, and effort changes are disabled while the team is live. Reconnect the team to apply them safely.'}
            </p>
          )}
        </div>
      )}
    </div>
  );
};
