import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Pencil, Trash2, Plus, Check, X, AlertTriangle } from 'lucide-react';
import { trpc } from '@/lib/trpc';
import { useNotify } from '@/hooks/useNotify';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Separator } from '@/components/ui/separator';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { SettingsCard } from './SettingsCard';
import { USE_CASES, TONES } from '@/components/onboarding/onboardingOptions';

/**
 * Keys managed by the "About you" curated panel — filtered out of CoreTable
 * so they don't appear twice.
 */
const CURATED_KEYS = new Set([
  'job_role',
  'industry',
  'primary_use_case',
  'tone_preference',
  'language',
  'user_name',
]);

const ALLOWED_PREDICATES = [
  'works_at',
  'reports_to',
  'stakeholder_of',
  'last_contacted_on',
  'owes_followup',
  'manages',
  'collaborates_with',
  'owns',
  'member_of',
  'custom',
] as const;

// ---------------------------------------------------------------------------
// AboutYouPanel — curated fields migrated from AIPreferencesSection
// ---------------------------------------------------------------------------

function AboutYouPanel() {
  const { t } = useTranslation();
  const authStatusQuery = trpc.auth.status.useQuery(undefined, {
    staleTime: 5 * 60 * 1000,
  });
  const updateMemoryMutation = trpc.auth.updateMemory.useMutation();
  const resetOnboardingMutation = trpc.auth.resetOnboarding.useMutation();
  const utils = trpc.useUtils();
  const { notify } = useNotify();

  const memory = authStatusQuery.data?.profile?.memory ?? {};

  const [jobRole, setJobRole] = useState('');
  const [industry, setIndustry] = useState('');
  const [useCase, setUseCase] = useState('');
  const [tone, setTone] = useState('');
  const [language, setLanguage] = useState('');

  useEffect(() => {
    setJobRole(memory.job_role ?? '');
    setIndustry(memory.industry ?? '');
    setUseCase(memory.primary_use_case ?? '');
    setTone(memory.tone_preference ?? '');
    setLanguage(memory.language ?? '');
  }, [memory.job_role, memory.industry, memory.primary_use_case, memory.tone_preference, memory.language]);

  function handleSave() {
    const mem: Record<string, string> = {};
    if (jobRole.trim()) mem.job_role = jobRole.trim();
    if (industry.trim()) mem.industry = industry.trim();
    if (useCase.trim()) mem.primary_use_case = useCase.trim();
    if (tone.trim()) mem.tone_preference = tone.trim();
    if (language.trim()) mem.language = language.trim();

    updateMemoryMutation.mutate(
      { memory: mem, markOnboarded: false },
      {
        onSuccess: () => {
          notify('success', 'toast.settings.memorySaved');
          void utils.auth.status.invalidate();
        },
      },
    );
  }

  function handleRerunOnboarding() {
    resetOnboardingMutation.mutate(undefined, {
      onSuccess: () => {
        notify('info', 'toast.onboarding.reset');
        void utils.auth.status.invalidate();
      },
    });
  }

  return (
    <SettingsCard
      title={t('settings.aboutYou')}
      description={t('settings.aboutYouDescription')}
    >
      <div className="flex flex-col gap-4">
        <div className="flex flex-col gap-1.5">
          <Label htmlFor="jobRole" className="text-xs">
            {t('settings.jobRole')}
          </Label>
          <Input
            id="jobRole"
            value={jobRole}
            onChange={(e) => setJobRole(e.target.value)}
            placeholder={t('settings.jobRolePlaceholder')}
          />
        </div>

        <div className="flex flex-col gap-1.5">
          <Label htmlFor="industry" className="text-xs">
            {t('settings.industry')}
          </Label>
          <Input
            id="industry"
            value={industry}
            onChange={(e) => setIndustry(e.target.value)}
            placeholder={t('settings.industryPlaceholder')}
          />
        </div>

        <div className="flex flex-col gap-1.5">
          <Label htmlFor="useCase" className="text-xs">
            {t('settings.primaryUseCase')}
          </Label>
          <Select value={useCase} onValueChange={setUseCase}>
            <SelectTrigger id="useCase" className="w-full">
              <SelectValue placeholder={t('settings.selectPlaceholder')} />
            </SelectTrigger>
            <SelectContent>
              {USE_CASES.map((uc) => (
                <SelectItem key={uc} value={uc}>
                  {uc}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <div className="flex flex-col gap-1.5">
          <Label htmlFor="tone" className="text-xs">
            {t('settings.tonePreference')}
          </Label>
          <Select value={tone} onValueChange={setTone}>
            <SelectTrigger id="tone" className="w-full">
              <SelectValue placeholder={t('settings.selectPlaceholder')} />
            </SelectTrigger>
            <SelectContent>
              {TONES.map((toneOption) => (
                <SelectItem key={toneOption} value={toneOption}>
                  {toneOption}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <div className="flex flex-col gap-1.5">
          <Label htmlFor="aiLanguage" className="text-xs">
            {t('settings.language')}
          </Label>
          <Input
            id="aiLanguage"
            value={language}
            onChange={(e) => setLanguage(e.target.value)}
            placeholder={t('settings.languagePlaceholder')}
          />
        </div>

        <div className="flex items-center gap-3 pt-1">
          <Button
            size="sm"
            onClick={handleSave}
            disabled={updateMemoryMutation.isPending}
          >
            {t('common.save')}
          </Button>
          <button
            onClick={handleRerunOnboarding}
            className="text-xs text-muted-foreground hover:text-foreground transition-colors"
            disabled={resetOnboardingMutation.isPending}
          >
            {t('settings.rerunOnboarding')}
          </button>
        </div>
      </div>
    </SettingsCard>
  );
}

// ---------------------------------------------------------------------------
// CoreTable — k/v pairs excluding curated keys
// ---------------------------------------------------------------------------

function CoreTable() {
  const { t } = useTranslation();
  const { notify, notifyError } = useNotify();
  const utils = trpc.useUtils();

  const coreQuery = trpc.memory.getCore.useQuery();
  const addCoreMutation = trpc.memory.addCore.useMutation();
  const deleteCoreMutation = trpc.memory.deleteCore.useMutation();

  const [editKey, setEditKey] = useState<string | null>(null);
  const [editValue, setEditValue] = useState('');
  const [newKey, setNewKey] = useState('');
  const [newValue, setNewValue] = useState('');

  // Filter out curated keys — they're displayed in AboutYouPanel above
  const entries = Object.entries(coreQuery.data ?? {}).filter(
    ([key]) => !CURATED_KEYS.has(key),
  );

  function startEdit(key: string, value: string) {
    setEditKey(key);
    setEditValue(value);
  }

  function cancelEdit() {
    setEditKey(null);
    setEditValue('');
  }

  function saveEdit(key: string) {
    if (!editValue.trim()) return;
    addCoreMutation.mutate(
      { key, value: editValue.trim() },
      {
        onSuccess: () => {
          notify('success', 'toast.settings.saved');
          void utils.memory.getCore.invalidate();
          setEditKey(null);
        },
        onError: (err) => notifyError('toast.settings.saveError', err),
      },
    );
  }

  function deleteKey(key: string) {
    deleteCoreMutation.mutate(
      { key },
      {
        onSuccess: () => {
          notify('success', 'toast.settings.saved');
          void utils.memory.getCore.invalidate();
        },
        onError: (err) => notifyError('toast.settings.saveError', err),
      },
    );
  }

  function addEntry() {
    if (!newKey.trim() || !newValue.trim()) return;
    addCoreMutation.mutate(
      { key: newKey.trim(), value: newValue.trim() },
      {
        onSuccess: () => {
          notify('success', 'toast.settings.saved');
          void utils.memory.getCore.invalidate();
          setNewKey('');
          setNewValue('');
        },
        onError: (err) => notifyError('toast.settings.saveError', err),
      },
    );
  }

  if (coreQuery.isLoading) {
    return <p className="text-xs text-muted-foreground">{t('common.loading', 'Loading…')}</p>;
  }

  return (
    <div className="space-y-2">
      {entries.length === 0 && (
        <p className="text-xs text-muted-foreground">{t('settings.memory.noEntries')}</p>
      )}
      {entries.map(([key, value]) => (
        <div key={key} className="flex items-center gap-2 text-sm">
          <span className="w-36 shrink-0 font-medium truncate text-muted-foreground">{key}</span>
          {editKey === key ? (
            <>
              <Input
                value={editValue}
                onChange={(e) => setEditValue(e.target.value)}
                className="h-7 text-sm flex-1"
                onKeyDown={(e) => { if (e.key === 'Enter') saveEdit(key); if (e.key === 'Escape') cancelEdit(); }}
                autoFocus
              />
              <Button size="icon" variant="ghost" className="h-7 w-7" onClick={() => saveEdit(key)}>
                <Check className="h-3.5 w-3.5" />
              </Button>
              <Button size="icon" variant="ghost" className="h-7 w-7" onClick={cancelEdit}>
                <X className="h-3.5 w-3.5" />
              </Button>
            </>
          ) : (
            <>
              <span className="flex-1 truncate">{value}</span>
              <Button size="icon" variant="ghost" className="h-7 w-7" onClick={() => startEdit(key, value)}>
                <Pencil className="h-3.5 w-3.5" />
              </Button>
              <Button
                size="icon"
                variant="ghost"
                className="h-7 w-7 text-destructive hover:text-destructive"
                onClick={() => deleteKey(key)}
                disabled={deleteCoreMutation.isPending}
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </>
          )}
        </div>
      ))}

      <Separator className="my-3" />
      <div className="flex items-center gap-2">
        <Input
          placeholder="key"
          value={newKey}
          onChange={(e) => setNewKey(e.target.value)}
          className="h-7 text-sm w-32"
        />
        <Input
          placeholder="value"
          value={newValue}
          onChange={(e) => setNewValue(e.target.value)}
          className="h-7 text-sm flex-1"
          onKeyDown={(e) => { if (e.key === 'Enter') addEntry(); }}
        />
        <Button size="icon" variant="ghost" className="h-7 w-7" onClick={addEntry} disabled={!newKey.trim() || !newValue.trim()}>
          <Plus className="h-3.5 w-3.5" />
        </Button>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// RelationalTable
// ---------------------------------------------------------------------------

function RelationalTable({ tier }: { tier: string }) {
  const { t } = useTranslation();
  const { notify, notifyError } = useNotify();
  const utils = trpc.useUtils();

  const relQuery = trpc.memory.listRelational.useQuery();
  const patchMutation = trpc.memory.patchRelation.useMutation();
  const deleteMutation = trpc.memory.deleteRelation.useMutation();

  const [editId, setEditId] = useState<string | null>(null);
  const [editPredicate, setEditPredicate] = useState('');

  if (tier === 'free') {
    return (
      <p className="text-xs text-muted-foreground">{t('settings.memory.upgradeToSeePeople')}</p>
    );
  }

  if (relQuery.isLoading) {
    return <p className="text-xs text-muted-foreground">{t('common.loading', 'Loading…')}</p>;
  }

  const rows = relQuery.data ?? [];

  function startEdit(id: string, predicate: string) {
    setEditId(id);
    setEditPredicate(predicate);
  }

  function cancelEdit() {
    setEditId(null);
    setEditPredicate('');
  }

  function savePredicate(id: string) {
    patchMutation.mutate(
      { id, predicate: editPredicate },
      {
        onSuccess: () => {
          notify('success', 'toast.settings.saved');
          void utils.memory.listRelational.invalidate();
          setEditId(null);
        },
        onError: (err) => notifyError('toast.settings.saveError', err),
      },
    );
  }

  function deleteRow(id: string) {
    deleteMutation.mutate(
      { id },
      {
        onSuccess: () => {
          notify('success', 'toast.settings.saved');
          void utils.memory.listRelational.invalidate();
        },
        onError: (err) => notifyError('toast.settings.saveError', err),
      },
    );
  }

  if (rows.length === 0) {
    return <p className="text-xs text-muted-foreground">{t('settings.memory.noEntries')}</p>;
  }

  return (
    <div className="space-y-2">
      {rows.map((row) => (
        <div key={row.id} className="flex items-center gap-2 text-sm">
          <span className="w-24 shrink-0 font-medium truncate">{row.subjectLabel}</span>
          {editId === row.id ? (
            <>
              <Select value={editPredicate} onValueChange={setEditPredicate}>
                <SelectTrigger className="h-7 text-xs w-36">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {ALLOWED_PREDICATES.map((p) => (
                    <SelectItem key={p} value={p} className="text-xs">{p}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Button size="icon" variant="ghost" className="h-7 w-7" onClick={() => savePredicate(row.id)}>
                <Check className="h-3.5 w-3.5" />
              </Button>
              <Button size="icon" variant="ghost" className="h-7 w-7" onClick={cancelEdit}>
                <X className="h-3.5 w-3.5" />
              </Button>
            </>
          ) : (
            <>
              <span className="text-xs text-muted-foreground w-32 truncate">{row.predicate}</span>
              <span className="flex-1 truncate">{row.objectLabel}</span>
              <div className="w-16 flex items-center gap-1">
                <div className="flex-1 h-1.5 rounded-full bg-muted overflow-hidden">
                  <div
                    className="h-full bg-primary rounded-full"
                    style={{ width: `${Math.round(row.confidence * 100)}%` }}
                  />
                </div>
                <span className="text-xs text-muted-foreground tabular-nums w-7 text-right">
                  {Math.round(row.confidence * 100)}%
                </span>
              </div>
              <Button size="icon" variant="ghost" className="h-7 w-7" onClick={() => startEdit(row.id, row.predicate)}>
                <Pencil className="h-3.5 w-3.5" />
              </Button>
              <Button
                size="icon"
                variant="ghost"
                className="h-7 w-7 text-destructive hover:text-destructive"
                onClick={() => deleteRow(row.id)}
                disabled={deleteMutation.isPending}
              >
                <Trash2 className="h-3.5 w-3.5" />
              </Button>
            </>
          )}
        </div>
      ))}
    </div>
  );
}

// ---------------------------------------------------------------------------
// ForgetAllDialog
// ---------------------------------------------------------------------------

function ForgetAllDialog() {
  const { t } = useTranslation();
  const { notify, notifyError } = useNotify();
  const utils = trpc.useUtils();
  const forgetMutation = trpc.memory.forgetAll.useMutation();
  const [confirmText, setConfirmText] = useState('');

  function handleForget() {
    forgetMutation.mutate(undefined, {
      onSuccess: () => {
        notify('success', 'toast.settings.saved');
        void utils.memory.getCore.invalidate();
        void utils.memory.listRelational.invalidate();
        setConfirmText('');
      },
      onError: (err) => notifyError('toast.settings.saveError', err),
    });
  }

  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button variant="outline" size="sm" className="text-destructive border-destructive/30 hover:bg-destructive/10">
          <AlertTriangle data-icon="inline-start" />
          {t('settings.memory.forgetEverything')}
        </Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>{t('settings.memory.dangerZone')}</AlertDialogTitle>
          <AlertDialogDescription>
            {t('settings.memory.forgetConfirm')}
          </AlertDialogDescription>
        </AlertDialogHeader>
        <Input
          placeholder={t('settings.memory.forgetEverything')}
          value={confirmText}
          onChange={(e) => setConfirmText(e.target.value)}
          className="mt-2"
        />
        <AlertDialogFooter>
          <AlertDialogCancel onClick={() => setConfirmText('')}>{t('common.cancel')}</AlertDialogCancel>
          <AlertDialogAction
            onClick={handleForget}
            disabled={confirmText.toLowerCase() !== 'forget' || forgetMutation.isPending}
            className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
          >
            {t('settings.memory.forgetEverything')}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

// ---------------------------------------------------------------------------
// MemorySection — root export
// ---------------------------------------------------------------------------

export function MemorySection() {
  const { t } = useTranslation();
  const authStatusQuery = trpc.auth.status.useQuery(undefined, { staleTime: 5 * 60 * 1000 });
  const tier = authStatusQuery.data?.profile?.tier ?? 'free';

  return (
    <div className="space-y-4">
      <AboutYouPanel />

      <SettingsCard
        title={t('settings.memory.otherFacts')}
        description={t('settings.memory.otherFactsDesc')}
      >
        <CoreTable />
      </SettingsCard>

      <SettingsCard
        title={t('settings.memory.peopleRelationships')}
        description={t('settings.memory.peopleRelationshipsDesc', 'People, companies, and projects the AI knows about.')}
      >
        <RelationalTable tier={tier} />
      </SettingsCard>

      <SettingsCard title={t('settings.memory.dangerZone')}>
        <div className="flex items-center justify-between">
          <div>
            <p className="text-sm font-medium text-destructive">{t('settings.memory.forgetEverything')}</p>
            <p className="text-xs text-muted-foreground">{t('settings.memory.forgetArea')}</p>
          </div>
          <ForgetAllDialog />
        </div>
      </SettingsCard>
    </div>
  );
}
