import { useRef, useState } from "react";

import { Icon } from "../../../components/Icon";
import { DOCUMENT_ACCEPT, formatBytes, validateDocumentFile } from "../file";
import type { DocumentJob, UploadPhase, UploadWorkflowState } from "../types";

interface DocumentUploadPanelProps {
  workflow: UploadWorkflowState;
  job: DocumentJob | undefined;
  onUpload: (file: File) => void;
  onCancel: () => void;
}

const ACTIVE_PHASES: UploadPhase[] = [
  "hashing",
  "declaring",
  "uploading",
  "completing",
  "parsing",
  "indexing",
];

const STEPS = [
  { phases: ["hashing", "declaring", "uploading", "completing"], label: "校验并隔离上传" },
  { phases: ["parsing"], label: "本地安全解析" },
  { phases: ["review"], label: "人工复核出域清单" },
  { phases: ["indexing", "indexed"], label: "向量化与激活" },
] as const;

function stepState(phase: UploadPhase, index: number): "pending" | "active" | "done" {
  if (phase === "indexed") return "done";
  const activeIndex = STEPS.findIndex((step) => (step.phases as readonly string[]).includes(phase));
  if (activeIndex === -1) return "pending";
  if (index < activeIndex) return "done";
  return index === activeIndex ? "active" : "pending";
}

export function DocumentUploadPanel({
  workflow,
  job,
  onUpload,
  onCancel,
}: DocumentUploadPanelProps) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [file, setFile] = useState<File | null>(null);
  const [selectionError, setSelectionError] = useState<string | null>(null);
  const busy = ACTIVE_PHASES.includes(workflow.phase);

  function chooseFile(next: File | undefined) {
    if (next === undefined) return;
    const error = validateDocumentFile(next);
    setSelectionError(error);
    setFile(error === null ? next : null);
  }

  return (
    <section
      className="document-panel document-upload-panel"
      aria-labelledby="document-upload-title"
    >
      <div className="section-heading">
        <div>
          <span className="eyebrow">INGESTION GATE</span>
          <h2 id="document-upload-title">导入本地资料</h2>
        </div>
        <span className="section-heading__meta">≤ 100 MiB</span>
      </div>

      <div
        className={`document-dropzone${selectionError === null ? "" : " document-dropzone--error"}`}
        onDragOver={(event) => event.preventDefault()}
        onDrop={(event) => {
          event.preventDefault();
          if (!busy) chooseFile(event.dataTransfer.files[0]);
        }}
      >
        <Icon name="document" size={27} />
        <strong>{file === null ? "选择或拖入地质资料" : file.name}</strong>
        <span>
          {file === null
            ? "支持 TXT、Markdown、DOCX、PDF"
            : `${formatBytes(file.size)} · 等待本地校验`}
        </span>
        <button
          className="secondary-button document-file-button"
          disabled={busy}
          onClick={() => inputRef.current?.click()}
          type="button"
        >
          选择文件
        </button>
        <input
          ref={inputRef}
          accept={DOCUMENT_ACCEPT}
          aria-label="选择待上传文档"
          className="visually-hidden"
          disabled={busy}
          onChange={(event) => chooseFile(event.target.files?.[0])}
          type="file"
        />
      </div>

      {selectionError !== null && (
        <p className="field-error" role="alert">
          {selectionError}
        </p>
      )}

      <div className="document-workflow" aria-label="文档处理阶段">
        {STEPS.map((step, index) => {
          const state = stepState(workflow.phase, index);
          return (
            <div
              className={`document-workflow__step document-workflow__step--${state}`}
              key={step.label}
            >
              <span aria-hidden="true">{state === "done" ? "✓" : index + 1}</span>
              <small>{step.label}</small>
            </div>
          );
        })}
      </div>

      <div className="document-live-status" aria-live="polite">
        <div>
          <strong>{workflow.filename ?? "尚未启动上传"}</strong>
          <span>{workflow.message ?? "文件只在浏览器计算摘要，模型密钥不会进入页面。"}</span>
        </div>
        {job !== undefined && (
          <div className="document-job-progress">
            <span>{job.stage}</span>
            <strong>{job.progress}%</strong>
          </div>
        )}
      </div>

      <div className="document-upload-actions">
        <button
          className="primary-button"
          disabled={file === null || busy}
          onClick={() => {
            if (file !== null) onUpload(file);
          }}
          type="button"
        >
          {busy && <span className="button-spinner" aria-hidden="true" />}
          {busy ? "处理中" : "校验并上传"}
        </button>
        {busy && (
          <button className="tertiary-button" onClick={onCancel} type="button">
            停止本页流程
          </button>
        )}
      </div>

      <p className="disabled-note">
        <Icon name="shield" size={15} />
        PDF 当前可能进入 OCR_REQUIRED；这不等同于地图空间理解，也不会自动提交云端模型。
      </p>
    </section>
  );
}
