"use client";

import { useState, useRef } from "react";
import { trpc } from "~/lib/trpc/client.js";
import { parseSkillMatrixWorkbook, matchRoleName } from "~/lib/skillMatrixParser.js";
import { assertSpreadsheetFile } from "~/lib/excel.js";
import type { SkillEntry } from "@nexus/shared";

interface ParsedEntry {
  fileName: string;
  candidateEid: string; // guessed from filename (no extension, lowercased)
  selectedEid: string;
  skills: SkillEntry[];
  employeeInfo: Record<string, string>;
  matchedRoleName: string | null;
  status: "pending" | "matched" | "unmatched";
}

export function BatchSkillImport() {
  const [entries, setEntries] = useState<ParsedEntry[]>([]);
  const [result, setResult] = useState<{ updated: number; notFound: number } | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  const { data: roles } = trpc.role.list.useQuery({ isActive: true }, { staleTime: 60_000 });
  const { data: resources } = trpc.resource.directory.useQuery(
    { isActive: true, limit: 500 },
    { staleTime: 60_000 },
  );

  const batchMutation = trpc.resource.batchImportSkillMatrices.useMutation({
    onSuccess: (data) => {
      setResult(data);
      setSubmitting(false);
    },
    onError: (err) => {
      setError(err.message);
      setSubmitting(false);
    },
  });

  async function handleFiles(e: React.ChangeEvent<HTMLInputElement>) {
    const files = Array.from(e.target.files ?? []);
    setResult(null);
    setError(null);

    const roleNames = (roles ?? []).map((r) => r.name);
    const resourceList = (resources?.resources ?? []) as SimpleResource[];

    const parsed: ParsedEntry[] = await Promise.all(
      files.map(async (file) => {
        const baseName = file.name.replace(/\.[^.]+$/, "");
        // Guess EID: try matching against resource displayName or eid
        const candidateEid = baseName.toLowerCase().replace(/\s+/g, ".");
        const matchedResource = resourceList.find(
          (r) =>
            r.eid.toLowerCase() === candidateEid ||
            r.displayName.toLowerCase().replace(/\s+/g, ".") === candidateEid ||
            r.displayName.toLowerCase() === baseName.toLowerCase(),
        );

        try {
          assertSpreadsheetFile(file, { allowCsv: false, contextLabel: "skill matrix import" });
          const buffer = await file.arrayBuffer();
          const result = await parseSkillMatrixWorkbook(buffer);

          let roleId: string | undefined;
          let matchedRoleName: string | undefined;
          if (result.employeeInfo.areaOfExpertise) {
            const matched = matchRoleName(result.employeeInfo.areaOfExpertise, roleNames);
            if (matched) {
              const role = (roles ?? []).find((r) => r.name === matched);
              roleId = role?.id;
              matchedRoleName = matched;
            }
          }

          const empInfo: Record<string, string> = {};
          if (roleId) empInfo["roleId"] = roleId;
          if (result.employeeInfo.portfolioUrl)
            empInfo["portfolioUrl"] = result.employeeInfo.portfolioUrl;

          return {
            fileName: file.name,
            candidateEid,
            selectedEid: matchedResource?.eid ?? candidateEid,
            skills: result.skills,
            employeeInfo: empInfo,
            matchedRoleName: matchedRoleName ?? null,
            status: matchedResource ? "matched" : "unmatched",
          } satisfies ParsedEntry;
        } catch {
          return {
            fileName: file.name,
            candidateEid,
            selectedEid: matchedResource?.eid ?? "",
            skills: [],
            employeeInfo: {},
            matchedRoleName: null,
            status: "unmatched",
          } satisfies ParsedEntry;
        }
      }),
    );

    setEntries(parsed);
  }

  function updateEid(idx: number, eid: string) {
    setEntries((prev) =>
      prev.map((e, i) =>
        i === idx
          ? {
              ...e,
              selectedEid: eid,
              status: eid ? "matched" : "unmatched",
            }
          : e,
      ),
    );
  }

  function handleImport() {
    const toImport = entries.filter((e) => e.selectedEid && e.skills.length > 0);
    if (toImport.length === 0) return;
    setSubmitting(true);
    batchMutation.mutate({
      entries: toImport.map((e) => ({
        eid: e.selectedEid,
        skills: e.skills,
        employeeInfo: {
          ...(e.employeeInfo["roleId"] ? { roleId: e.employeeInfo["roleId"] } : {}),
          ...(e.employeeInfo["portfolioUrl"]
            ? { portfolioUrl: e.employeeInfo["portfolioUrl"] }
            : {}),
        },
      })),
    });
  }

  type SimpleResource = { eid: string; displayName: string };
  const resourceList = (resources?.resources ?? []) as SimpleResource[];
  const matched = entries.filter((e) => e.status === "matched").length;
  const unmatched = entries.filter((e) => e.status === "unmatched").length;

  return (
    <div className="p-6 max-w-4xl">
      <div className="mb-6">
        <h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
          Batch Skill Matrix Import
        </h1>
        <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
          Upload multiple skill matrix files at once. Files are matched to resources by filename.
        </p>
      </div>

      {/* Upload area */}
      <div
        className="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-xl p-8 text-center cursor-pointer hover:border-brand-400 transition-colors mb-6 bg-white dark:bg-gray-800"
        onClick={() => fileRef.current?.click()}
      >
        <svg
          className="w-10 h-10 text-gray-300 dark:text-gray-600 mx-auto mb-3"
          fill="none"
          viewBox="0 0 24 24"
          stroke="currentColor"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={1.5}
            d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
          />
        </svg>
        <p className="text-sm font-medium text-gray-700 dark:text-gray-300">
          Click to select multiple .xlsx files
        </p>
        <p className="text-xs text-gray-400 dark:text-gray-500 mt-1">
          Name files after resource EID or display name for automatic matching
        </p>
        <input
          ref={fileRef}
          type="file"
          accept=".xlsx"
          multiple
          className="hidden"
          onChange={handleFiles}
        />
      </div>

      {/* Summary */}
      {entries.length > 0 && (
        <div className="flex gap-4 mb-4">
          <div className="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-700 rounded-lg px-4 py-2 text-sm">
            <span className="font-semibold text-green-700 dark:text-green-400">{matched}</span>
            <span className="text-green-600 dark:text-green-400 ml-1">matched</span>
          </div>
          <div className="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-700 rounded-lg px-4 py-2 text-sm">
            <span className="font-semibold text-yellow-700 dark:text-yellow-400">{unmatched}</span>
            <span className="text-yellow-600 dark:text-yellow-400 ml-1">
              unmatched (select EID manually)
            </span>
          </div>
        </div>
      )}

      {/* Entries table */}
      {entries.length > 0 && (
        <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden mb-6">
          <table className="w-full text-sm">
            <thead className="bg-gray-50 dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700">
              <tr>
                <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase">
                  File
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase">
                  Resource EID
                </th>
                <th className="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase">
                  Skills
                </th>
                <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase">
                  Role Match
                </th>
                <th className="px-4 py-3 text-center text-xs font-medium text-gray-500 dark:text-gray-400 uppercase">
                  Status
                </th>
              </tr>
            </thead>
            <tbody className="divide-y divide-gray-100 dark:divide-gray-700">
              {entries.map((entry, idx) => (
                <tr
                  key={idx}
                  className={
                    entry.status === "unmatched" ? "bg-yellow-50 dark:bg-yellow-900/10" : ""
                  }
                >
                  <td className="px-4 py-3 text-xs text-gray-600 dark:text-gray-400 font-mono">
                    {entry.fileName}
                  </td>
                  <td className="px-4 py-3">
                    {entry.status === "matched" ? (
                      <span className="font-mono text-sm text-gray-800 dark:text-gray-100">
                        {entry.selectedEid}
                      </span>
                    ) : (
                      <select
                        className="w-full px-2 py-1.5 border border-yellow-300 dark:border-yellow-600 rounded text-sm bg-white dark:bg-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-brand-500"
                        value={entry.selectedEid}
                        onChange={(e) => updateEid(idx, e.target.value)}
                      >
                        <option value="">— Select resource —</option>
                        {resourceList.map((r) => (
                          <option key={r.eid} value={r.eid}>
                            {r.displayName} ({r.eid})
                          </option>
                        ))}
                      </select>
                    )}
                  </td>
                  <td className="px-4 py-3 text-right text-gray-700 dark:text-gray-300">
                    {entry.skills.length}
                  </td>
                  <td className="px-4 py-3 text-xs text-gray-500 dark:text-gray-400">
                    {entry.matchedRoleName ?? "—"}
                  </td>
                  <td className="px-4 py-3 text-center">
                    <span
                      className={`inline-block px-2 py-0.5 text-xs rounded-full font-medium ${
                        entry.status === "matched"
                          ? "bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400"
                          : "bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-400"
                      }`}
                    >
                      {entry.status}
                    </span>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {error && (
        <div className="mb-4 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700 px-4 py-3 text-sm text-red-700 dark:text-red-400">
          {error}
        </div>
      )}

      {result && (
        <div className="mb-4 rounded-lg bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-700 px-4 py-3 text-sm text-green-700 dark:text-green-400">
          Import complete: <strong>{result.updated}</strong> updated,{" "}
          <strong>{result.notFound}</strong> not found.
        </div>
      )}

      {entries.length > 0 && !result && (
        <button
          type="button"
          onClick={handleImport}
          disabled={submitting || matched === 0}
          className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 text-sm font-medium disabled:opacity-50"
        >
          {submitting
            ? "Importing…"
            : `Import ${entries.filter((e) => e.selectedEid && e.skills.length > 0).length} Files`}
        </button>
      )}
    </div>
  );
}
