import { type Dispatch, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import {
  AlertTriangle,
  CheckCircle2,
  Copy,
  Download,
  FolderTree,
  XCircle,
} from 'lucide-react';
import {
  Button,
  Input,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  cn,
  listDatasetFiles,
} from '@ump/shared';
import { FolderUploadButtons } from '../../../dataset-workspace/presentation/FolderUploadButtons';
import { FolderTreeView } from '../../../dataset-workspace/presentation/FolderTreeView';
import {
  datasetFolderName,
  generateBashScript,
  generateCloudScript,
  generatePythonScript,
  type DatasetCase,
  type DatasetMeta,
  type Operation,
  type PlannedFile,
  type SourceFile,
  type Split,
  type Target,
  type ValidationReport,
} from '../../domain/nnunet/core';
import type { NnunetAction, NnunetWizardState } from '../../domain/nnunet/wizardState';
import { StepHead } from './steps';

// ---------- Step 3 — Cases ----------

interface CasesStepProps {
  datasetId: string;
  state: NnunetWizardState;
  dispatch: Dispatch<NnunetAction>;
  cases: DatasetCase[];
  unassigned: SourceFile[];
  report: ValidationReport;
  onAddFiles: (files: FileList | File[]) => void;
  /** Returns error messages (empty = imported OK). */
  onImportItemsList: (json: string) => string[];
  onLoadExample: () => void;
}

export function CasesStep({ datasetId }: CasesStepProps) {
  const filesQ = useQuery({
    queryKey: ['imagehub', 'dataset', datasetId, 'files'],
    queryFn: () => listDatasetFiles(datasetId),
    enabled: !!datasetId,
  });

  return (
    <div>
      <StepHead title="Các case" sub="Tải ảnh gốc và nhãn trực tiếp vào bộ dữ liệu." />

      <div className="space-y-3">
        <FolderUploadButtons datasetId={datasetId} />
        <FolderTreeView files={filesQ.data ?? []} />
      </div>
    </div>
  );
}

// ---------- Step 4 — Validate & export ----------

function download(name: string, text: string) {
  const url = URL.createObjectURL(new Blob([text], { type: 'application/octet-stream' }));
  const a = document.createElement('a');
  a.href = url;
  a.download = name;
  a.click();
  URL.revokeObjectURL(url);
}

interface ExportStepProps {
  meta: DatasetMeta;
  report: ValidationReport;
  datasetJson: Record<string, unknown>;
  plan: PlannedFile[];
  folderName: string;
}

export function ExportStep({ meta, report, datasetJson, plan, folderName }: ExportStepProps) {
  const jsonText = JSON.stringify(datasetJson, null, 2);
  const manifest = JSON.stringify(plan.map((p) => ({ from: p.source.filename, to: p.targetPath })), null, 2);

  const [operation, setOperation] = useState<Operation>('copy');
  const [target, setTarget] = useState<Target>('local');
  const [srcRoot, setSrcRoot] = useState('');
  const [dstRoot, setDstRoot] = useState('');
  const [scriptTab, setScriptTab] = useState<'bash' | 'python'>('bash');
  const [copied, setCopied] = useState('');

  const copy = (key: string, text: string) => {
    navigator.clipboard?.writeText(text).then(() => {
      setCopied(key);
      setTimeout(() => setCopied(''), 1200);
    });
  };

  const opts = { operation, target, sourceRoot: srcRoot, destRoot: dstRoot };
  const isLocal = target === 'local';
  const script = isLocal
    ? scriptTab === 'python'
      ? generatePythonScript(meta, plan, datasetJson, opts)
      : generateBashScript(meta, plan, datasetJson, opts)
    : generateCloudScript(meta, plan, datasetJson, opts);
  const scriptName = isLocal ? (scriptTab === 'python' ? `organize_${folderName}.py` : `organize_${folderName}.sh`) : `upload_${folderName}.sh`;
  const cfg = meta.dim === '2d' ? '2d' : '3d_fullres';

  return (
    <div>
      <StepHead title="Kiểm tra & xuất" sub="Xử lý lỗi, xuất dataset.json, rồi sinh script đưa tệp vào đúng vị trí." />

      <div className="mb-4 space-y-1.5">
        {report.issues.length === 0 && (
          <div className="flex items-center gap-2 rounded-lg bg-emerald-50 p-3 text-sm text-emerald-700">
            <CheckCircle2 className="h-4 w-4" /> Mọi kiểm tra đều đạt.
          </div>
        )}
        {report.issues.map((it, i) => (
          <div key={i} className={cn('flex items-start gap-2 rounded-lg p-2.5 text-sm', it.level === 'error' ? 'bg-destructive/10 text-destructive' : 'bg-amber-50 text-amber-700')}>
            {it.level === 'error' ? <XCircle className="mt-0.5 h-4 w-4 shrink-0" /> : <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" />}
            <span>
              {it.caseId && <span className="mr-1.5 rounded bg-background/60 px-1.5 py-0.5 font-mono text-xs">{it.caseId}</span>}
              {it.message}
            </span>
          </div>
        ))}
      </div>

      <div className="mb-6 flex flex-wrap gap-2">
        <Button disabled={!report.ok} onClick={() => download('dataset.json', jsonText)}>
          <Download className="mr-1.5 h-4 w-4" /> dataset.json
        </Button>
        <Button variant="outline" disabled={!report.ok} onClick={() => download(`${folderName}_manifest.json`, manifest)}>
          <FolderTree className="mr-1.5 h-4 w-4" /> Manifest di chuyển
        </Button>
        <Button variant="ghost" onClick={() => copy('json', jsonText)}>
          <Copy className="mr-1.5 h-4 w-4" /> {copied === 'json' ? 'Đã chép' : 'Chép dataset.json'}
        </Button>
      </div>

      <div className="border-t border-border pt-4">
        <div className="text-base font-semibold text-foreground">Thực thi di chuyển</div>
        <p className="mb-3.5 mt-0.5 max-w-2xl text-sm text-muted-foreground">
          Sinh script tạo thư mục, ghi dataset.json và {operation === 'move' ? 'di chuyển' : 'sao chép'} từng tệp tới đúng đường dẫn. Xem lại rồi chạy nơi dữ liệu của bạn.
        </p>

        <div className="mb-3.5 flex flex-wrap items-end gap-4">
          <div>
            <div className="mb-1.5 text-xs font-medium text-foreground">Thao tác</div>
            <div className="inline-flex overflow-hidden rounded-lg border border-border">
              {(['copy', 'move'] as Operation[]).map((o) => (
                <button
                  key={o}
                  type="button"
                  onClick={() => setOperation(o)}
                  className={cn('px-3 py-1.5 text-sm font-medium transition', operation === o ? 'bg-primary text-primary-foreground' : 'bg-card text-muted-foreground hover:bg-muted')}
                >
                  {o === 'copy' ? 'Sao chép' : 'Di chuyển'}
                </button>
              ))}
            </div>
          </div>
          <div>
            <div className="mb-1.5 text-xs font-medium text-foreground">Đích đến</div>
            <Select value={target} onValueChange={(v) => setTarget(v as Target)}>
              <SelectTrigger className="w-44">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="local">Hệ thống tệp cục bộ</SelectItem>
                <SelectItem value="s3">Amazon S3</SelectItem>
                <SelectItem value="gcs">Google Cloud Storage</SelectItem>
                <SelectItem value="azure">Azure Blob</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        <div className="mb-3.5 grid max-w-2xl gap-4 sm:grid-cols-2">
          <label className="block">
            <div className="mb-1.5 text-xs font-medium text-foreground">Thư mục nguồn</div>
            <Input className="font-mono" value={srcRoot} onChange={(e) => setSrcRoot(e.target.value)} placeholder={isLocal ? './incoming' : 'nguồn'} />
          </label>
          <label className="block">
            <div className="mb-1.5 text-xs font-medium text-foreground">Thư mục đích</div>
            <Input className="font-mono" value={dstRoot} onChange={(e) => setDstRoot(e.target.value)} placeholder={isLocal ? './data_raw' : 'đích'} />
          </label>
        </div>

        {!report.ok && (
          <div className="mb-3 flex items-start gap-2 rounded-lg bg-amber-50 p-2.5 text-sm text-amber-700">
            <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" />
            <span>Bộ dữ liệu còn lỗi — hãy sửa trước khi chạy script trên dữ liệu thật.</span>
          </div>
        )}

        <div className="overflow-hidden rounded-xl border border-border">
          <div className="flex items-center gap-1 border-b border-border bg-muted/50 px-2 pt-2">
            {isLocal ? (
              (['bash', 'python'] as const).map((t) => (
                <button
                  key={t}
                  type="button"
                  onClick={() => setScriptTab(t)}
                  className={cn('rounded-t-lg px-3 py-1.5 text-xs font-medium', scriptTab === t ? 'bg-card text-primary' : 'text-muted-foreground')}
                >
                  {t === 'bash' ? 'Bash' : 'Python'}
                </button>
              ))
            ) : (
              <span className="rounded-t-lg bg-card px-3 py-1.5 text-xs font-medium text-primary">Cloud CLI</span>
            )}
            <div className="ml-auto flex gap-1.5 pb-1.5">
              <Button variant="ghost" size="sm" className="h-7" onClick={() => copy('script', script)}>
                <Copy className="mr-1 h-3 w-3" /> {copied === 'script' ? 'Đã chép' : 'Chép'}
              </Button>
              <Button size="sm" className="h-7" onClick={() => download(scriptName, script)}>
                <Download className="mr-1 h-3 w-3" /> {scriptName}
              </Button>
            </div>
          </div>
          <pre className="m-0 max-h-72 overflow-auto whitespace-pre bg-muted/30 p-3.5 font-mono text-xs leading-relaxed text-foreground">{script}</pre>
        </div>

        <div className="mt-3.5 rounded-lg border border-border bg-muted/40 p-3 text-xs text-muted-foreground">
          <b className="text-foreground">Kiểm tra &amp; huấn luyện:</b>{' '}
          kiểm tra tính toàn vẹn dữ liệu rồi huấn luyện bằng công cụ của bạn (cấu hình <b>{cfg}</b>).
        </div>
      </div>
    </div>
  );
}
