"use client";

import { useCallback, useRef, useState } from "react";
import { ImportHistoryList } from "@/components/imports/import-history-list";
import { PageLayout } from "@/components/design-system/page-layout";
import { Button } from "@/components/ui/button";
import { ImportProgressBar } from "@/components/imports/import-progress-bar";
import { ImportSummaryCard } from "@/components/imports/import-summary";
import type {
  ImportDetectResult,
  ImportMappingMatch,
  ImportPreviewResult,
  ImportProgressState,
  ImportResultStats,
  ImportStatus,
  ImportStatusResponse,
} from "@/types/import";
import { emptyImportResultStats } from "@/lib/import-result-stats";

type ImportMode = "auto" | "simple" | "processed";

export function ImportsClient({
  initialHistory = [],
}: {
  initialHistory?: unknown[];
}) {
  const [file, setFile] = useState<File | null>(null);
  const [importMode, setImportMode] = useState<ImportMode>("auto");
  const [mappingJson, setMappingJson] = useState("{}");
  const [detectResult, setDetectResult] = useState<ImportDetectResult | null>(
    null
  );
  const [previewResult, setPreviewResult] = useState<ImportPreviewResult | null>(
    null
  );
  const [importProgress, setImportProgress] = useState<ImportProgressState | null>(
    null
  );
  const [importStatus, setImportStatus] = useState<ImportStatus | null>(null);
  const [resultStats, setResultStats] = useState<ImportResultStats | null>(null);
  const [errorCount, setErrorCount] = useState(0);
  const [history, setHistory] = useState<unknown[]>(initialHistory);
  const [loading, setLoading] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const executingRef = useRef(false);

  const loadHistory = useCallback(async () => {
    const res = await fetch("/api/imports/history");
    if (!res.ok) return;
    const data = await res.json();
    setHistory(data.data ?? []);
  }, []);

  function buildFormData(): FormData {
    const formData = new FormData();
    if (!file) throw new Error("اختر ملفاً أولاً.");
    formData.append("file", file);
    formData.append("importType", importMode);
    if (importMode === "simple" || importMode === "auto") {
      const trimmed = mappingJson.trim();
      if (trimmed && trimmed !== "{}") {
        formData.append("mapping", mappingJson);
      }
    }
    return formData;
  }

  function applySuggestedMapping(result: ImportDetectResult) {
    if (result.suggestedMapping) {
      setMappingJson(JSON.stringify(result.suggestedMapping, null, 2));
    }
  }

  async function handleDetect() {
    setError(null);
    setLoading("detect");
    try {
      const res = await fetch("/api/imports/detect", {
        method: "POST",
        body: buildFormData(),
      });
      const data = (await res.json()) as ImportDetectResult & {
        error?: string;
      };
      if (!res.ok) throw new Error(data.error ?? "فشل الكشف.");
      setDetectResult(data);
      if (data.detectedType === "simple" || importMode === "simple") {
        applySuggestedMapping(data);
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "فشل الكشف.");
    } finally {
      setLoading(null);
    }
  }

  async function handlePreview() {
    setError(null);
    setLoading("preview");
    try {
      const res = await fetch("/api/imports/preview", {
        method: "POST",
        body: buildFormData(),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error ?? "فشل المعاينة.");
      setPreviewResult(data);
      if (data.mappingUsed) {
        setMappingJson(JSON.stringify(data.mappingUsed, null, 2));
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "فشل المعاينة.");
    } finally {
      setLoading(null);
    }
  }

  async function pollImportStatus(importLogId: string): Promise<void> {
    const terminal: ImportStatus[] = [
      "completed",
      "failed",
      "partially_completed",
    ];

    for (let attempt = 0; attempt < 600; attempt++) {
      await new Promise((r) => setTimeout(r, 1000));
      const res = await fetch(`/api/imports/status/${importLogId}`);
      if (!res.ok) continue;
      const data = (await res.json()) as ImportStatusResponse;
      setImportProgress(data.progress);
      setImportStatus(data.status);
      setResultStats(data.resultStats);
      setErrorCount(data.errorCount);

      if (terminal.includes(data.status)) {
        await loadHistory();
        return;
      }
    }
    setError("انتهت مهلة انتظار الاستيراد. تحقق من سجل الاستيراد.");
  }

  async function handleExecute() {
    if (executingRef.current) return;
    setError(null);
    setImportProgress(null);
    setImportStatus("processing");
    setResultStats(null);
    setLoading("execute");
    executingRef.current = true;

    try {
      const res = await fetch("/api/imports/execute", {
        method: "POST",
        body: buildFormData(),
      });
      const data = await res.json();
      if (res.status === 409) {
        throw new Error(data.error ?? "استيراد قيد التنفيذ بالفعل.");
      }
      if (!res.ok && res.status !== 202) {
        throw new Error(data.error ?? "فشل الاستيراد.");
      }

      const importLogId = data.importLogId as string;
      if (!importLogId) {
        throw new Error("لم يُرجع معرّف سجل الاستيراد.");
      }

      setImportProgress({
        stage: "uploaded",
        percent: 5,
        processedRows: 0,
        totalRows: 0,
        message: "جاري قراءة الملف",
      });

      await pollImportStatus(importLogId);
    } catch (e) {
      setError(e instanceof Error ? e.message : "فشل الاستيراد.");
      setImportStatus("failed");
    } finally {
      setLoading(null);
      executingRef.current = false;
    }
  }

  const isExecuting = loading === "execute";

  const showMappingUi = importMode === "simple" || importMode === "auto";
  const mappingMatches: ImportMappingMatch[] =
    detectResult?.mappingMatches ??
    (previewResult as { mappingMatches?: ImportMappingMatch[] })?.mappingMatches ??
    [];

  return (
    <PageLayout
      title="استيراد البيانات"
      description="استيراد بسيط (ورقة واحدة + تعيين أعمدة تلقائي) أو معالج (ملف GPT متعدد الأوراق)."
      className="max-w-4xl"
    >
      <section className="surface-elevated space-y-4 p-5">
        <div>
          <label className="mb-1 block text-sm font-medium">ملف Excel</label>
          <input
            type="file"
            accept=".xlsx,.xls,.csv"
            onChange={(e) => setFile(e.target.files?.[0] ?? null)}
            className="block w-full text-sm"
          />
        </div>

        <div>
          <label className="mb-1 block text-sm font-medium">نوع الاستيراد</label>
          <select
            value={importMode}
            onChange={(e) => setImportMode(e.target.value as ImportMode)}
            className="flex h-10 w-full rounded-lg border border-border bg-card px-3 py-2 text-sm"
          >
            <option value="auto">كشف تلقائي</option>
            <option value="simple">استيراد بسيط</option>
            <option value="processed">استيراد معالج (GPT)</option>
          </select>
        </div>

        {showMappingUi ? (
          <div className="space-y-3">
            <p className="text-sm text-neutral-600">
              تم تعيين الأعمدة تلقائياً. يمكنك تعديلها قبل الاستيراد إذا لزم.
            </p>
            {detectResult?.mappingConfidence != null ? (
              <p className="text-sm text-neutral-700">
                ثقة التعيين:{" "}
                <span className="font-medium">
                  {(detectResult.mappingConfidence * 100).toFixed(0)}%
                </span>
              </p>
            ) : null}
            {mappingMatches.length > 0 ? (
              <MappingMatchesTable matches={mappingMatches} />
            ) : null}
            <div>
              <label className="mb-1 block text-sm font-medium">
                تعيين الأعمدة (JSON) — اختياري للتعديل
              </label>
              <textarea
                value={mappingJson}
                onChange={(e) => setMappingJson(e.target.value)}
                rows={8}
                className="w-full rounded-md border border-neutral-300 px-3 py-2 font-mono text-xs"
                dir="ltr"
                placeholder='{"companyName":"company_name","email":"email"}'
              />
            </div>
          </div>
        ) : null}

        <div className="flex flex-wrap gap-2">
          <button
            type="button"
            disabled={!file || loading !== null}
            onClick={() => void handleDetect()}
            className="rounded-lg border border-border px-4 py-2 text-sm hover:bg-muted disabled:opacity-50"
          >
            {loading === "detect" ? "جاري الكشف..." : "كشف النوع"}
          </button>
          <button
            type="button"
            disabled={!file || loading !== null}
            onClick={() => void handlePreview()}
            className="rounded-lg border border-border px-4 py-2 text-sm hover:bg-muted disabled:opacity-50"
          >
            {loading === "preview" ? "جاري المعاينة..." : "معاينة"}
          </button>
          <button
            type="button"
            disabled={!file || loading !== null || isExecuting}
            onClick={() => void handleExecute()}
            className="rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-50"
          >
            {isExecuting ? "جاري الاستيراد..." : "تنفيذ الاستيراد"}
          </button>
        </div>

        {importProgress && isExecuting ? (
          <ImportProgressBar progress={importProgress} />
        ) : null}

        {error ? (
          <p className="rounded-md bg-red-50 px-3 py-2 text-sm text-red-700">
            {error}
          </p>
        ) : null}
      </section>

      {detectResult ? (
        <ResultCard title="نتيجة الكشف">
          <pre className="overflow-auto text-xs" dir="ltr">
            {JSON.stringify(detectResult, null, 2)}
          </pre>
        </ResultCard>
      ) : null}

      {previewResult ? (
        <ResultCard title="معاينة الاستيراد">
          <PreviewStatsPanel result={previewResult} />
        </ResultCard>
      ) : null}

      {importStatus &&
      (importStatus === "completed" ||
        importStatus === "partially_completed" ||
        importStatus === "failed") &&
      !isExecuting ? (
        <ImportSummaryCard
          status={importStatus}
          resultStats={resultStats ?? emptyImportResultStats()}
          errorCount={errorCount}
        />
      ) : null}

      <section className="surface-elevated p-5">
        <div className="flex items-center justify-between gap-4">
          <h2 className="text-title text-lg">سجل الاستيراد الأخير</h2>
          <Button type="button" variant="outline" size="sm" onClick={() => void loadHistory()}>
            تحديث
          </Button>
        </div>
        <div className="mt-3">
          <ImportHistoryList items={history} />
        </div>
      </section>
    </PageLayout>
  );
}

function MappingMatchesTable({ matches }: { matches: ImportMappingMatch[] }) {
  return (
    <div className="overflow-x-auto rounded-md border border-neutral-200">
      <table className="min-w-full text-xs">
        <thead>
          <tr className="bg-neutral-50 text-neutral-600">
            <th className="px-2 py-2 text-right">حقل النظام</th>
            <th className="px-2 py-2 text-right">العمود المكتشف</th>
            <th className="px-2 py-2 text-right">الثقة</th>
            <th className="px-2 py-2 text-right">السبب</th>
          </tr>
        </thead>
        <tbody>
          {matches.map((m) => (
            <tr key={`${m.standardField}-${m.originalHeader}`} className="border-t">
              <td className="px-2 py-1.5 font-mono" dir="ltr">
                {m.standardField}
              </td>
              <td className="px-2 py-1.5">{m.originalHeader}</td>
              <td className="px-2 py-1.5">
                {(m.confidence * 100).toFixed(0)}%
              </td>
              <td className="px-2 py-1.5 text-neutral-600">{m.reason}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function PreviewStatsPanel({ result }: { result: ImportPreviewResult }) {
  const s = result.stats;
  return (
    <ul className="space-y-1 text-sm text-neutral-700">
      <li>الصفوف: {s.totalRowsFound}</li>
      <li>شركات (متوقع): {s.companiesExtracted}</li>
      <li>أشخاص (متوقع): {s.peopleExtracted}</li>
      <li>اتصالات (متوقع): {s.contactsExtracted}</li>
      <li>مشكلات: {s.issuesFound}</li>
    </ul>
  );
}

function ResultCard({
  title,
  children,
}: {
  title: string;
  children: React.ReactNode;
}) {
  return (
    <section className="surface-elevated p-5">
      <h2 className="text-lg font-semibold">{title}</h2>
      <div className="mt-3">{children}</div>
    </section>
  );
}
