import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { formatDistanceToNow } from 'date-fns';
import { api } from '../../lib/api';
import { useAuthStore } from '../../lib/auth';
import type { VttKind, VttVersionSummary, DiffLine } from '../../types/api';

interface Props {
  jobId: string;
  /** Available languages from job.outputs keys */
  languages: string[];
  /** Source language (default selection) */
  defaultLang: string;
}

const KIND_LABELS: Record<VttKind, string> = { captions: 'Captions', ad: 'Audio Description' };

function bytesLabel(n: number): string {
  if (n < 1024) return `${n} B`;
  return `${(n / 1024).toFixed(1)} KB`;
}

function DiffViewer({ lines }: { lines: DiffLine[] }) {
  const BG: Record<DiffLine['type'], string> = {
    unchanged: '',
    added: 'bg-green-50',
    removed: 'bg-red-50',
  };
  const TEXT: Record<DiffLine['type'], string> = {
    unchanged: 'text-gray-700',
    added: 'text-green-800',
    removed: 'text-red-800 line-through',
  };
  const PREFIX: Record<DiffLine['type'], string> = {
    unchanged: ' ',
    added: '+',
    removed: '−',
  };

  return (
    <div className="overflow-auto max-h-[60vh] text-xs font-mono border border-gray-200 rounded">
      {lines.map((line, i) => (
        <div key={i} className={`flex ${BG[line.type]}`}>
          <span className="w-6 shrink-0 text-center text-gray-400 border-r border-gray-200 select-none">
            {PREFIX[line.type]}
          </span>
          <span className={`px-2 py-0.5 whitespace-pre-wrap break-all ${TEXT[line.type]}`}>
            {line.content || ' '}
          </span>
        </div>
      ))}
    </div>
  );
}

function VersionRow({
  v,
  isSelected,
  isCompareA,
  isCompareB,
  onSelect,
  onSetA,
  onSetB,
  onRestore,
  canRestore,
}: {
  v: VttVersionSummary;
  isSelected: boolean;
  isCompareA: boolean;
  isCompareB: boolean;
  onSelect: () => void;
  onSetA: () => void;
  onSetB: () => void;
  onRestore: () => void;
  canRestore: boolean;
}) {
  return (
    <div
      className={`flex items-center justify-between p-3 rounded border cursor-pointer transition-colors ${
        isSelected ? 'border-blue-400 bg-blue-50' : 'border-gray-200 hover:bg-gray-50'
      }`}
      onClick={onSelect}
    >
      <div className="flex items-center gap-3 min-w-0">
        <span className="shrink-0 font-mono text-xs text-gray-500 w-7">v{v.version}</span>
        <div className="min-w-0">
          <p className="text-sm text-gray-800 truncate">
            {v.note ?? `Saved by ${v.created_by.user_email.split('@')[0]}`}
          </p>
          <p className="text-xs text-gray-400">
            {formatDistanceToNow(new Date(v.created_at))} ago · {v.cue_count} cues · {bytesLabel(v.byte_size)}
          </p>
        </div>
      </div>
      <div className="flex items-center gap-1 shrink-0 ml-2" onClick={e => e.stopPropagation()}>
        <button
          onClick={onSetA}
          title="Set as A (left side of diff)"
          className={`px-2 py-0.5 text-xs rounded border ${isCompareA ? 'bg-indigo-600 text-white border-indigo-600' : 'border-gray-300 text-gray-600 hover:bg-gray-100'}`}
        >A</button>
        <button
          onClick={onSetB}
          title="Set as B (right side of diff)"
          className={`px-2 py-0.5 text-xs rounded border ${isCompareB ? 'bg-purple-600 text-white border-purple-600' : 'border-gray-300 text-gray-600 hover:bg-gray-100'}`}
        >B</button>
        {canRestore && (
          <button
            onClick={onRestore}
            className="px-2 py-0.5 text-xs rounded border border-orange-300 text-orange-700 hover:bg-orange-50"
          >
            Restore
          </button>
        )}
      </div>
    </div>
  );
}

export function VersionsTab({ jobId, languages, defaultLang }: Props) {
  const { user } = useAuthStore();
  const queryClient = useQueryClient();
  const canRestore = user?.role === 'production' || user?.role === 'admin';

  const [lang, setLang] = useState(defaultLang);
  const [kind, setKind] = useState<VttKind>('captions');
  const [selectedVersion, setSelectedVersion] = useState<number | null>(null);
  const [compareA, setCompareA] = useState<number | null>(null);
  const [compareB, setCompareB] = useState<number | null>(null);
  const [confirmRestore, setConfirmRestore] = useState<number | null>(null);

  const listKey = ['vtt-versions', jobId, lang, kind];
  const { data: listData, isLoading } = useQuery({
    queryKey: listKey,
    queryFn: () => api.listVttVersions(jobId, lang, kind),
    enabled: !!jobId,
  });

  const { data: selectedContent, isLoading: contentLoading } = useQuery({
    queryKey: ['vtt-version-content', jobId, lang, kind, selectedVersion],
    queryFn: () => api.getVttVersion(jobId, lang, kind, selectedVersion!),
    enabled: selectedVersion !== null,
  });

  const { data: diffData, isLoading: diffLoading } = useQuery({
    queryKey: ['vtt-diff', jobId, lang, kind, compareA, compareB],
    queryFn: () => api.diffVttVersions(jobId, lang, kind, compareA!, compareB!),
    enabled: compareA !== null && compareB !== null && compareA !== compareB,
  });

  const restoreMutation = useMutation({
    mutationFn: (version: number) => api.restoreVttVersion(jobId, lang, kind, version),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: listKey });
      queryClient.invalidateQueries({ queryKey: ['job', jobId] });
      setConfirmRestore(null);
    },
  });

  const versions = listData?.versions ?? [];
  const showDiff = compareA !== null && compareB !== null && compareA !== compareB;

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-6">
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-lg font-medium text-gray-900">Edit History</h2>
        <div className="flex items-center gap-2">
          {/* Language selector */}
          {languages.length > 1 && (
            <select
              value={lang}
              onChange={e => { setLang(e.target.value); setSelectedVersion(null); setCompareA(null); setCompareB(null); }}
              className="text-sm border border-gray-300 rounded-md px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500"
            >
              {languages.map(l => <option key={l} value={l}>{l.toUpperCase()}</option>)}
            </select>
          )}
          {/* Kind selector */}
          <div className="flex rounded-md border border-gray-300 overflow-hidden text-sm">
            {(['captions', 'ad'] as VttKind[]).map(k => (
              <button
                key={k}
                onClick={() => { setKind(k); setSelectedVersion(null); setCompareA(null); setCompareB(null); }}
                className={`px-3 py-1 ${kind === k ? 'bg-blue-600 text-white' : 'text-gray-600 hover:bg-gray-50'}`}
              >
                {KIND_LABELS[k]}
              </button>
            ))}
          </div>
        </div>
      </div>

      {isLoading && (
        <div className="animate-pulse space-y-2">
          {[1, 2, 3].map(i => <div key={i} className="h-14 bg-gray-200 rounded" />)}
        </div>
      )}

      {!isLoading && versions.length === 0 && (
        <p className="text-gray-500 text-sm text-center py-8">
          No versions yet. Versions are created automatically each time a VTT file is saved.
        </p>
      )}

      {versions.length > 0 && (
        <div className="flex gap-4">
          {/* Version list */}
          <div className="w-80 shrink-0 space-y-2 max-h-[60vh] overflow-y-auto pr-1">
            {showDiff && (
              <p className="text-xs text-gray-500 px-1">
                Comparing <span className="font-medium text-indigo-600">A=v{compareA}</span> → <span className="font-medium text-purple-600">B=v{compareB}</span>
                {' '}<button className="underline text-gray-400 hover:text-gray-600" onClick={() => { setCompareA(null); setCompareB(null); }}>Clear</button>
              </p>
            )}
            {versions.map(v => (
              <VersionRow
                key={v.version}
                v={v}
                isSelected={selectedVersion === v.version && !showDiff}
                isCompareA={compareA === v.version}
                isCompareB={compareB === v.version}
                onSelect={() => { setSelectedVersion(v.version); setCompareA(null); setCompareB(null); }}
                onSetA={() => { setCompareA(v.version); setSelectedVersion(null); }}
                onSetB={() => { setCompareB(v.version); setSelectedVersion(null); }}
                onRestore={() => setConfirmRestore(v.version)}
                canRestore={canRestore}
              />
            ))}
          </div>

          {/* Right panel */}
          <div className="flex-1 min-w-0">
            {/* Diff view */}
            {showDiff && (
              <div>
                <div className="flex items-center justify-between mb-2">
                  <h3 className="text-sm font-medium text-gray-700">
                    Diff: <span className="text-indigo-600">v{compareA}</span> → <span className="text-purple-600">v{compareB}</span>
                  </h3>
                  {diffData && (
                    <span className="text-xs text-gray-500">
                      <span className="text-green-600">+{diffData.added_count}</span>
                      {' '}<span className="text-red-600">−{diffData.removed_count}</span>
                    </span>
                  )}
                </div>
                {diffLoading && <p className="text-sm text-gray-400">Computing diff…</p>}
                {diffData && <DiffViewer lines={diffData.lines} />}
              </div>
            )}

            {/* Single version content */}
            {!showDiff && selectedVersion !== null && (
              <div>
                <h3 className="text-sm font-medium text-gray-700 mb-2">v{selectedVersion} — content</h3>
                {contentLoading && <p className="text-sm text-gray-400">Loading…</p>}
                {selectedContent && (
                  <pre className="text-xs font-mono bg-gray-50 border border-gray-200 rounded p-3 overflow-auto max-h-[60vh] whitespace-pre-wrap break-all">
                    {selectedContent.content}
                  </pre>
                )}
              </div>
            )}

            {/* Placeholder */}
            {!showDiff && selectedVersion === null && (
              <div className="flex items-center justify-center h-40 text-gray-400 text-sm">
                Select a version to view its content, or set A + B to diff
              </div>
            )}
          </div>
        </div>
      )}

      {/* Restore confirmation dialog */}
      {confirmRestore !== null && (
        <div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
          <div className="bg-white rounded-lg shadow-xl p-6 max-w-sm w-full mx-4">
            <h3 className="text-lg font-medium text-gray-900 mb-2">Restore v{confirmRestore}?</h3>
            <p className="text-sm text-gray-600 mb-4">
              This will overwrite the live {KIND_LABELS[kind]} VTT with the content from v{confirmRestore}
              and create a new version entry. The action is logged and reversible.
            </p>
            <div className="flex gap-3 justify-end">
              <button
                onClick={() => setConfirmRestore(null)}
                className="px-4 py-2 text-sm border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50"
              >
                Cancel
              </button>
              <button
                disabled={restoreMutation.isPending}
                onClick={() => restoreMutation.mutate(confirmRestore)}
                className="px-4 py-2 text-sm bg-orange-600 text-white rounded-md hover:bg-orange-700 disabled:opacity-50"
              >
                {restoreMutation.isPending ? 'Restoring…' : 'Restore'}
              </button>
            </div>
            {restoreMutation.isError && (
              <p className="text-red-600 text-xs mt-2">Restore failed. Please try again.</p>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
