import { useEffect, useRef, useState } from "react";
import { Check, RefreshCw, RotateCcw, X } from "lucide-react";
import { HttpError } from "../../shared/api/errors";
import { DocumentType } from "../../shared/api/enums";
import { notifyContentChanged } from "../../shared/state/contentRefresh";
import { useDictionaries } from "../dictionaries/dictionaryContext";
import { invalidateDetail } from "../documents/documentState";
import { invalidatePreview } from "../files/fileState";
import { recycleBinApi } from "./recycleBinApi";
import {
  RESTORE_DESCRIPTIONS,
  RESTORE_ERROR_MESSAGES,
  deletedByLabel,
  formatLocalDate,
} from "./recycleBinLabels";
import type {
  RecycleBinDocumentSummary,
  RestoreDocumentResult,
} from "./recycleBinTypes";

const NAVY = "#1A5299";
const BLUE = "#3191eb";

export function RestoreDocumentModal({
  item,
  onClose,
  onRestored,
  onConflict,
}: {
  item: RecycleBinDocumentSummary;
  onClose: () => void;
  onRestored: (result: RestoreDocumentResult) => void;
  onConflict: () => void;
}) {
  const dictionaries = useDictionaries();
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<HttpError | null>(null);
  const [result, setResult] = useState<RestoreDocumentResult | null>(null);
  const controller = useRef<AbortController | null>(null);
  const requestLocked = useRef(false);

  useEffect(
    () => () => {
      controller.current?.abort();
    },
    [],
  );

  const restore = async () => {
    if (requestLocked.current || result) return;
    requestLocked.current = true;
    setSubmitting(true);
    setError(null);
    controller.current = new AbortController();
    try {
      const response = await recycleBinApi.restore(
        item.id,
        { rowVersion: item.rowVersion },
        controller.current.signal,
      );
      invalidateDetail(
        item.documentType === DocumentType.ATTACHMENT
          ? "attachment"
          : "document",
        item.id,
      );
      if (item.parentDocumentId) {
        invalidateDetail("document", item.parentDocumentId);
      }
      notifyContentChanged("documents", "attachments");
      invalidatePreview(item.id);
      setResult(response.data);
      onRestored(response.data);
    } catch (value) {
      if (controller.current.signal.aborted) return;
      const next =
        value instanceof HttpError
          ? value
          : new HttpError({
              httpStatus: 0,
              code: "INTERNAL_ERROR",
              message: "恢复请求失败",
              details: null,
              requestId: "client",
              cause: value,
            });
      setError(next);
      if (next.code === "DATA_VERSION_CONFLICT") onConflict();
    } finally {
      requestLocked.current = false;
      setSubmitting(false);
    }
  };

  const skipped =
    (result?.skippedPermissionCount ?? 0) +
    (result?.skippedBindingCount ?? 0);

  return (
    <div
      className="fixed inset-0 z-[80] flex items-center justify-center"
      style={{ background: "rgba(26,82,153,.58)" }}
      onClick={onClose}
    >
      <div
        className="w-[650px] max-h-[88vh] overflow-auto bg-white shadow-2xl"
        onClick={(event) => event.stopPropagation()}
      >
        <div
          className="h-11 px-5 flex items-center justify-between text-white"
          style={{ background: NAVY }}
        >
          <span className="font-black">恢复回收站文档</span>
          <button onClick={onClose} disabled={submitting}>
            <X size={17} />
          </button>
        </div>
        <div className="p-6 space-y-4" style={{ color: NAVY }}>
          <div className="grid grid-cols-2 gap-3 text-sm font-bold">
            <div>
              <span className="opacity-60">文档名称：</span>
              {item.documentName}
            </div>
            <div>
              <span className="opacity-60">文档类型：</span>
              {dictionaries.label("documentTypes", item.documentType)}
            </div>
            <div>
              <span className="opacity-60">删除时间：</span>
              {formatLocalDate(item.deletedAt)}
            </div>
            <div>
              <span className="opacity-60">删除人：</span>
              {deletedByLabel(item.deletedBy)}
            </div>
          </div>
          <div
            className="p-4 text-sm font-bold leading-7"
            style={{ background: "#EBF4FD" }}
          >
            {RESTORE_DESCRIPTIONS[item.documentType]}
          </div>
          {error && (
            <div
              className="p-3 text-sm font-bold leading-6"
              style={{ background: "rgba(26,82,153,.08)" }}
            >
              <div>
                {RESTORE_ERROR_MESSAGES[error.code] ?? error.message}
              </div>
              {error.requestId && (
                <div className="text-xs opacity-60">
                  错误编号：{error.requestId}
                </div>
              )}
            </div>
          )}

          {result && (
            <div
              className="p-4 text-sm font-bold leading-7"
              style={{
                background: skipped ? "rgba(26,82,153,.1)" : "#EBF4FD",
              }}
            >
              <div className="flex items-center gap-2 font-black">
                <Check size={16} style={{ color: BLUE }} />
                文档恢复成功
              </div>
              <div>
                权限：恢复 {result.restoredPermissionCount} 条，跳过{" "}
                {result.skippedPermissionCount} 条
              </div>
              <div>
                挂载：恢复 {result.restoredBindingCount} 条，跳过{" "}
                {result.skippedBindingCount} 条
              </div>
              {skipped > 0 && (
                <div className="mt-1 font-black">
                  文档已恢复，但有 {result.skippedPermissionCount} 条无效权限和{" "}
                  {result.skippedBindingCount} 条无效挂载未恢复。
                </div>
              )}
            </div>
          )}

          <div className="flex justify-end gap-2">
            <button
              onClick={onClose}
              disabled={submitting}
              className="px-4 py-2 text-sm font-black border"
              style={{ borderColor: BLUE }}
            >
              {result ? "完成" : "取消"}
            </button>
            {!result && (
              <button
                onClick={() => void restore()}
                disabled={submitting}
                className="px-4 py-2 text-sm font-black text-white disabled:opacity-50"
                style={{ background: BLUE }}
              >
                {submitting ? (
                  <>
                    <RefreshCw size={13} className="inline animate-spin mr-1" />
                    恢复中
                  </>
                ) : (
                  <>
                    <RotateCcw size={13} className="inline mr-1" />
                    确认恢复
                  </>
                )}
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
