// Data-import PRESENTATION — §7.3 UploadDataDialog. A multi-step Direct Upload wizard hosted in a
// shared Dialog (mirrors SegmentationUploadDialog). Steps are driven entirely by the §3 machine
// state; the §5 task preview + validation errors come straight from the domain. Side effects live
// in the use-case behind useDirectUpload.

import { useEffect, useRef, type ChangeEvent, type ReactNode } from 'react';
import { AlertCircle, CheckCircle2, FileImage, Loader2, Upload, FolderUp } from 'lucide-react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
  Button,
  Label,
  Checkbox,
} from '@ump/shared';
import { DATA_TYPES, DATA_TYPE_LABELS_VI, supportsGroupByStudy } from '../../domain';
import { useDirectUpload } from '../hooks/useDirectUpload';
import { PrivacyNotice } from './PrivacyNotice';

interface UploadDataDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  datasetId: string;
  /** Called once tasks are created so the caller can refetch the dataset file list. */
  onCompleted: () => void;
}

export function UploadDataDialog({ open, onOpenChange, datasetId, onCompleted }: UploadDataDialogProps) {
  const u = useDirectUpload(datasetId);
  const { machine, taskPreview } = u;
  const { state, context } = machine;
  const fileInput = useRef<HTMLInputElement>(null);
  const dirInput = useRef<HTMLInputElement>(null);

  const busy = state === 'Validating' || state === 'Uploading' || state === 'Processing';
  const editing = state === 'SelectingType' || state === 'ConfiguringStructure' || state === 'Staging';

  // A directory picker needs the non-standard webkitdirectory attribute, set imperatively.
  useEffect(() => {
    if (dirInput.current) dirInput.current.setAttribute('webkitdirectory', '');
  }, []);

  // Refetch the dataset's files once tasks are created.
  useEffect(() => {
    if (state === 'Complete') onCompleted();
  }, [state, onCompleted]);

  const onPick = (e: ChangeEvent<HTMLInputElement>) => {
    const picked = Array.from(e.target.files ?? []);
    if (picked.length) u.addFiles(picked);
    e.target.value = '';
  };

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!busy) onOpenChange(o);
      }}
    >
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Nhập dữ liệu — Tải lên trực tiếp</DialogTitle>
          <DialogDescription>
            Chọn loại dữ liệu, thêm tệp (hoặc cả thư mục), rồi tải lên. Hệ thống nhóm tệp thành các tác vụ
            (task) theo loại.
          </DialogDescription>
        </DialogHeader>

        {/* ---- Editing: type selection + structure + staging ---- */}
        {editing && (
          <div className="space-y-4">
            {/* Type chips (D1 — one type; changing it clears staged files). */}
            <div>
              <Label className="text-xs text-muted-foreground">Loại dữ liệu</Label>
              <div className="mt-1 flex flex-wrap gap-2">
                {DATA_TYPES.map((t) => {
                  const active = context.dataType === t;
                  return (
                    <button
                      key={t}
                      type="button"
                      onClick={() => u.selectType(t)}
                      className={`rounded-full border px-3 py-1 text-sm transition-colors ${
                        active
                          ? 'border-primary bg-primary text-primary-foreground'
                          : 'hover:border-primary hover:bg-accent/30'
                      }`}
                    >
                      {DATA_TYPE_LABELS_VI[t]}
                    </button>
                  );
                })}
              </div>
            </div>

            {context.dataType === null ? (
              <p className="text-sm text-muted-foreground">Chọn một loại dữ liệu để bắt đầu.</p>
            ) : (
              <>
                {/* D2 — Group by Study only for DICOM/NIfTI. */}
                {supportsGroupByStudy(context.dataType) && (
                  <div className="flex items-center gap-2">
                    <Checkbox
                      id="gbs"
                      checked={context.groupByStudy}
                      onCheckedChange={() => u.toggleGroupByStudy()}
                    />
                    <Label htmlFor="gbs" className="text-sm font-normal">
                      Nhóm theo nghiên cứu (Group by Study) — gộp các tệp cùng thư mục thành một tác vụ.
                    </Label>
                  </div>
                )}

                <PrivacyNotice />

                {/* File / folder pickers. */}
                <div className="flex flex-wrap gap-2">
                  <input ref={fileInput} type="file" multiple className="hidden" onChange={onPick} />
                  <input ref={dirInput} type="file" multiple className="hidden" onChange={onPick} />
                  <Button variant="outline" size="sm" onClick={() => fileInput.current?.click()}>
                    <Upload className="mr-2 h-4 w-4" /> Chọn tệp…
                  </Button>
                  <Button variant="outline" size="sm" onClick={() => dirInput.current?.click()}>
                    <FolderUp className="mr-2 h-4 w-4" /> Chọn thư mục…
                  </Button>
                  {context.files.length > 0 && (
                    <Button variant="ghost" size="sm" onClick={() => u.clearFiles()}>
                      Xóa hết
                    </Button>
                  )}
                </div>

                {/* Validation errors (after a failed VALIDATE). */}
                {context.errors.length > 0 && (
                  <div className="space-y-1 rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive">
                    <p className="flex items-center gap-1 font-medium">
                      <AlertCircle className="h-4 w-4" /> Có {context.errors.length} lỗi cần sửa:
                    </p>
                    <ul className="list-disc pl-5">
                      {context.errors.slice(0, 8).map((e, i) => (
                        <li key={i}>{e.message}</li>
                      ))}
                    </ul>
                  </div>
                )}

                {/* §5 task preview. */}
                {context.files.length > 0 && (
                  <div className="rounded-md border p-3 text-sm">
                    <p className="mb-2 text-muted-foreground">
                      <strong className="text-foreground">{context.files.length}</strong> tệp →{' '}
                      <strong className="text-foreground">{taskPreview.length}</strong> tác vụ
                    </p>
                    <div className="max-h-40 space-y-1 overflow-y-auto">
                      {taskPreview.slice(0, 12).map((t) => (
                        <div key={`${t.grouping}-${t.name}`} className="flex items-center gap-2 text-xs">
                          <FileImage className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                          <span className="font-mono">{t.name}</span>
                          <span className="text-muted-foreground">
                            ({t.files.length} tệp · {t.grouping})
                          </span>
                        </div>
                      ))}
                      {taskPreview.length > 12 && (
                        <p className="text-xs text-muted-foreground">… và {taskPreview.length - 12} tác vụ khác</p>
                      )}
                    </div>
                  </div>
                )}
              </>
            )}
          </div>
        )}

        {/* ---- Busy + terminal states ---- */}
        {state === 'Validating' && <Centered icon="spin">Đang kiểm tra tệp…</Centered>}
        {state === 'Uploading' && (
          <div className="space-y-2 py-4">
            <p className="text-sm text-muted-foreground">Đang tải lên máy chủ…</p>
            <div className="h-2 w-full overflow-hidden rounded bg-muted">
              <div
                className="h-2 rounded bg-primary transition-[width] duration-300"
                style={{ width: `${context.progress}%` }}
              />
            </div>
          </div>
        )}
        {state === 'Processing' && <Centered icon="spin">Đang xử lý trên máy chủ…</Centered>}
        {state === 'Complete' && (
          <Centered icon="ok">
            Đã tạo {context.createdTaskIds.length} tệp/tác vụ trong bộ dữ liệu.
          </Centered>
        )}
        {(state === 'UploadError' || state === 'PartialFailure') && (
          <div className="space-y-1 rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive">
            <p className="flex items-center gap-1 font-medium">
              <AlertCircle className="h-4 w-4" />{' '}
              {state === 'UploadError' ? 'Tải lên thất bại.' : 'Một số tác vụ chưa hoàn tất.'}
            </p>
            {context.errors.slice(0, 5).map((e, i) => (
              <p key={i}>{e.message}</p>
            ))}
          </div>
        )}

        <DialogFooter>
          {editing && (
            <>
              <Button variant="ghost" onClick={() => onOpenChange(false)}>
                Hủy
              </Button>
              <Button
                onClick={() => void u.start()}
                disabled={state === 'SelectingType' || context.files.length === 0}
              >
                <Upload className="mr-2 h-4 w-4" /> Tải lên {context.files.length || ''}
              </Button>
            </>
          )}
          {busy && (
            <Button disabled>
              <Loader2 className="mr-2 h-4 w-4 animate-spin" /> Đang xử lý…
            </Button>
          )}
          {state === 'Complete' && <Button onClick={() => onOpenChange(false)}>Đóng</Button>}
          {(state === 'UploadError' || state === 'PartialFailure') && (
            <>
              <Button variant="ghost" onClick={() => onOpenChange(false)}>
                Hủy
              </Button>
              <Button onClick={() => void u.start()}>Thử lại</Button>
            </>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function Centered({ icon, children }: { icon: 'spin' | 'ok'; children: ReactNode }) {
  return (
    <div className="flex flex-col items-center gap-2 py-8 text-center text-sm">
      {icon === 'spin' ? (
        <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
      ) : (
        <CheckCircle2 className="h-6 w-6 text-emerald-600" />
      )}
      <p>{children}</p>
    </div>
  );
}

export default UploadDataDialog;
