"use client";

import { useActionState, useRef, useState } from "react";
import { useFormStatus } from "react-dom";
import { previewAction, confirmImportAction, type ImportState } from "./actions";
import type { ImportKind } from "@/lib/import";

const KIND_LABEL: Record<ImportKind, string> = {
  "san-pham": "Danh mục sản phẩm",
  "khach-hang": "Danh sách khách hàng",
  "don-hang": "Đơn hàng lịch sử",
};

function Submit({ label, pendingLabel }: { label: string; pendingLabel: string }) {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className="btn-primary" disabled={pending}>
      {pending ? pendingLabel : label}
    </button>
  );
}

export function ImportForm({
  requiredColumns,
  optionalColumns,
}: {
  requiredColumns: Record<ImportKind, string[]>;
  optionalColumns: Record<ImportKind, string[]>;
}) {
  const [kind, setKind] = useState<ImportKind>("san-pham");
  const [fileName, setFileName] = useState<string>("");
  const fileRef = useRef<HTMLInputElement>(null);

  const [previewState, runPreview] = useActionState<ImportState, FormData>(previewAction, {});
  const [confirmState, runConfirm] = useActionState<ImportState, FormData>(confirmImportAction, {});

  const preview = previewState.preview;
  const result = confirmState.result;
  const canConfirm = preview && preview.errors.length === 0 && preview.validRows > 0;

  return (
    <div className="flex flex-col gap-5">
      {/* Bước 1 — chọn loại và file */}
      <form action={runPreview} className="card flex flex-col gap-4 p-4">
        <div className="grid gap-4 lg:grid-cols-2">
          <div>
            <label htmlFor="kind" className="label-caps mb-1.5 block">
              Loại dữ liệu
            </label>
            <select
              id="kind"
              name="kind"
              value={kind}
              onChange={(event) => setKind(event.target.value as ImportKind)}
              className="input"
            >
              {(Object.keys(KIND_LABEL) as ImportKind[]).map((key) => (
                <option key={key} value={key}>
                  {KIND_LABEL[key]}
                </option>
              ))}
            </select>
          </div>

          <div>
            <label htmlFor="file" className="label-caps mb-1.5 block">
              File Excel (.xlsx)
            </label>
            <input
              ref={fileRef}
              id="file"
              name="file"
              type="file"
              accept=".xlsx"
              required
              onChange={(event) => setFileName(event.target.files?.[0]?.name ?? "")}
              className="input file:mr-3 file:rounded file:border-0 file:bg-ink-100 file:px-3 file:py-1 file:text-sm file:text-ink-600"
            />
          </div>
        </div>

        {/* Cột yêu cầu của loại đang chọn */}
        <div className="rounded-lg bg-ink-50 px-4 py-3 text-sm">
          <p className="mb-1 font-semibold text-ink-700">Dòng đầu tiên của file phải là tên cột.</p>
          <p className="text-ink-500">
            <span className="font-semibold">Bắt buộc:</span> {requiredColumns[kind].join(" · ")}
          </p>
          {optionalColumns[kind].length > 0 && (
            <p className="mt-0.5 text-ink-400">
              <span className="font-semibold">Tuỳ chọn:</span> {optionalColumns[kind].join(" · ")}
            </p>
          )}
          {kind === "khach-hang" && (
            <p className="mt-1.5 text-ink-400">
              Khách <b>mới</b> (mã chưa có) phải có đủ: Tên đơn vị, Kênh, Người liên hệ, Điện thoại, Khu vực (tỉnh); khách trạng thái Đang / Đại lý cần thêm
              Phường / Xã và Địa chỉ. Tên Kênh, Khu vực, NVKD phải đúng như trong danh mục — gõ sai sẽ báo lỗi ở đúng dòng. Dòng có Mã KH đã tồn tại là
              <b> cập nhật</b>: ô để trống nghĩa là giữ nguyên dữ liệu hiện có.
            </p>
          )}
          {kind === "don-hang" && (
            <p className="mt-1.5 text-ink-400">
              Mỗi dòng là một mặt hàng. Các dòng cùng &ldquo;Mã đơn&rdquo; được gom thành một đơn.
              Mã đơn đã có trong hệ thống sẽ được bỏ qua để không nhân đôi doanh thu.
            </p>
          )}
        </div>

        <div className="flex items-center gap-3">
          <Submit label="Kiểm tra file" pendingLabel="Đang đọc file…" />
          {fileName && <span className="text-xs text-ink-400">{fileName}</span>}
        </div>

        {previewState.error && (
          <p role="alert" className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
            {previewState.error}
          </p>
        )}
      </form>

      {/* Bước 2 — kết quả kiểm tra */}
      {preview && !result && (
        <div className="card p-4">
          <h2 className="mb-3 text-base font-bold text-ink-700">Kết quả kiểm tra</h2>

          <div className="mb-4 grid grid-cols-3 gap-3">
            <div>
              <div className="label-caps">Tổng số dòng</div>
              <div className="tnum text-xl font-bold text-ink-700">{preview.totalRows}</div>
            </div>
            <div>
              <div className="label-caps">Dòng hợp lệ</div>
              <div className="tnum text-xl font-bold text-brand-600">{preview.validRows}</div>
            </div>
            <div>
              <div className="label-caps">Dòng lỗi</div>
              <div
                className={`tnum text-xl font-bold ${preview.errors.length > 0 ? "text-red-600" : "text-ink-400"}`}
              >
                {new Set(preview.errors.map((e) => e.row)).size}
              </div>
            </div>
          </div>

          {preview.errors.length > 0 ? (
            <>
              <p className="mb-2 text-sm text-ink-600">
                File còn lỗi nên chưa nhập được. Sửa các dòng dưới đây rồi tải lại file — hệ thống
                không ghi một phần, tránh để lại dữ liệu dở dang.
              </p>
              <div className="max-h-72 overflow-y-auto rounded-lg border border-[var(--color-line)]">
                <table className="data-table">
                  <thead>
                    <tr>
                      <th style={{ width: 90 }}>Dòng</th>
                      <th>Lỗi</th>
                    </tr>
                  </thead>
                  <tbody>
                    {preview.errors.map((error, index) => (
                      <tr key={index}>
                        <td className="tnum text-ink-400">{error.row > 0 ? error.row : "—"}</td>
                        <td className="text-ink-700">{error.message}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </>
          ) : (
            <p className="text-sm text-brand-600">
              File hợp lệ. Kiểm tra lại vài dòng mẫu bên dưới rồi bấm xác nhận.
            </p>
          )}

          {preview.sample.length > 0 && (
            <div className="mt-4">
              <div className="label-caps mb-2">Dòng mẫu</div>
              <div className="overflow-x-auto rounded-lg border border-[var(--color-line)]">
                <table className="data-table">
                  <thead>
                    <tr>
                      {Object.keys(preview.sample[0]).map((header) => (
                        <th key={header}>{header}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {preview.sample.map((row, index) => (
                      <tr key={index}>
                        {Object.keys(preview.sample[0]).map((header) => (
                          <td key={header} className="whitespace-nowrap text-ink-600">
                            {row[header]}
                          </td>
                        ))}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}

          {canConfirm && (
            <form
              action={(formData) => {
                // Server action không giữ được file giữa hai lần gọi, nên gắn lại
                // đúng file người dùng vừa chọn ở bước kiểm tra.
                const file = fileRef.current?.files?.[0];
                if (file) formData.set("file", file);
                formData.set("kind", preview.kind);
                runConfirm(formData);
              }}
              className="mt-4 flex items-center gap-3"
            >
              <Submit label={`Xác nhận nhập ${preview.validRows} dòng`} pendingLabel="Đang ghi dữ liệu…" />
              <span className="text-xs text-ink-400">
                Sản phẩm và khách hàng đã có mã trùng sẽ được cập nhật, không tạo bản ghi mới.
              </span>
            </form>
          )}
        </div>
      )}

      {/* Bước 3 — kết quả nhập */}
      {result && (
        <div className="card p-4">
          <h2 className="mb-3 text-base font-bold text-ink-700">Đã nhập xong</h2>
          <div className="grid grid-cols-2 gap-3">
            <div>
              <div className="label-caps">Thêm mới</div>
              <div className="tnum text-xl font-bold text-brand-600">{result.inserted}</div>
            </div>
            <div>
              <div className="label-caps">Cập nhật</div>
              <div className="tnum text-xl font-bold text-ink-700">{result.updated}</div>
            </div>
          </div>
          {result.errors.length > 0 && (
            <ul className="mt-3 flex flex-col gap-1 text-sm text-ink-500">
              {result.errors.map((error, index) => (
                <li key={index}>{error.message}</li>
              ))}
            </ul>
          )}
          <p className="mt-3 text-xs text-ink-400">
            Phân hạng đại lý và KPI được tính lại trong lần chạy job hằng đêm gần nhất, hoặc bấm
            &ldquo;Tính lại số liệu&rdquo; trong trang Danh mục.
          </p>
        </div>
      )}

      {confirmState.error && (
        <p role="alert" className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
          {confirmState.error}
        </p>
      )}
    </div>
  );
}
