"use client";

import { useState, useId } from "react";
import dynamic from "next/dynamic";
import { SortableColumnHeader } from "~/components/ui/SortableColumnHeader.js";
import { useTableSort } from "~/hooks/useTableSort.js";
import { trpc } from "~/lib/trpc/client.js";
import * as XLSX from "xlsx";

const SkillDistributionChart = dynamic(
  () => import("~/components/analytics/SkillDistributionChart.js"),
  { ssr: false, loading: () => <div className="h-80 shimmer-skeleton rounded-xl" /> },
);

const PROFICIENCY_LABELS = ["", "Aware", "Basic", "Intermediate", "Advanced", "Expert"];

// Tailwind class sets per proficiency level (1–5), dark-mode aware
const PROFICIENCY_CLASSES = [
  "bg-gray-100 text-gray-700 border-gray-300 dark:bg-gray-700 dark:text-gray-200 dark:border-gray-500",
  "bg-blue-100 text-blue-800 border-blue-300 dark:bg-blue-900/60 dark:text-blue-200 dark:border-blue-600",
  "bg-indigo-100 text-indigo-800 border-indigo-300 dark:bg-indigo-900/60 dark:text-indigo-200 dark:border-indigo-500",
  "bg-amber-100 text-amber-800 border-amber-300 dark:bg-amber-900/60 dark:text-amber-200 dark:border-amber-500",
  "bg-green-100 text-green-800 border-green-300 dark:bg-green-900/60 dark:text-green-200 dark:border-green-500",
];

function proficiencyClasses(level: number): string {
  const idx = Math.max(0, Math.min(4, Math.round(level) - 1));
  return PROFICIENCY_CLASSES[idx] ?? PROFICIENCY_CLASSES[0]!;
}

function ProficiencyBadge({ value }: { value: number }) {
  return (
    <span className={`inline-block px-2 py-0.5 text-xs rounded font-medium border ${proficiencyClasses(value)}`}>
      {value} {PROFICIENCY_LABELS[value] ?? ""}
    </span>
  );
}

type SkillRule = { skill: string; minProficiency: number };

export function SkillsAnalytics() {
  const datalistId = useId();

  // ── Skill table filters ──────────────────────────────────────────────────
  const [categoryFilter, setCategoryFilter] = useState<string>("");
  const [minCount, setMinCount] = useState<number>(1);
  const [skillSearch, setSkillSearch] = useState<string>("");

  // ── People Finder ────────────────────────────────────────────────────────
  const [rules, setRules] = useState<SkillRule[]>([]);
  const [operator, setOperator] = useState<"AND" | "OR">("AND");
  const [peopleChapter, setPeopleChapter] = useState<string>("");

  const { data, isLoading, error } = trpc.resource.getSkillsAnalytics.useQuery(undefined, {
    staleTime: 60_000,
  });

  const activeRules = rules.filter((r) => r.skill.trim().length > 0);
  const { data: peopleResults, isFetching: peopleFetching } =
    trpc.resource.searchBySkills.useQuery(
      {
        rules: activeRules,
        operator,
        ...(peopleChapter ? { chapter: peopleChapter } : {}),
      },
      {
        enabled: activeRules.length > 0,
        staleTime: 30_000,
      },
    );

  function addRule() {
    setRules((prev) => [...prev, { skill: "", minProficiency: 1 }]);
  }

  function removeRule(idx: number) {
    setRules((prev) => prev.filter((_, i) => i !== idx));
  }

  function updateRule(idx: number, patch: Partial<SkillRule>) {
    setRules((prev) => prev.map((r, i) => (i === idx ? { ...r, ...patch } : r)));
  }

  async function exportXlsx() {
    if (!data) return;
    const XLSX = await import("xlsx");
    const rows = data.aggregated.map((e) => ({
      Skill: e.skill,
      Category: e.category,
      "# Resources": e.count,
      "Avg Proficiency": e.avgProficiency,
      Chapters: e.chapters.join(", "),
    }));
    const ws = XLSX.utils.json_to_sheet(rows);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Skills");
    XLSX.writeFile(wb, `skills-analytics-${Date.now()}.xlsx`);
  }

  const allSkillNames = (data?.aggregated ?? []).map((e) => e.skill);

  const filtered = (data?.aggregated ?? []).filter((e) => {
    if (categoryFilter && e.category !== categoryFilter) return false;
    if (e.count < minCount) return false;
    if (skillSearch && !e.skill.toLowerCase().includes(skillSearch.toLowerCase())) return false;
    return true;
  });

  const { sorted: sortedSkills, sortField: skillSortField, sortDir: skillSortDir, toggle: skillToggle } = useTableSort(filtered);
  const top20 = filtered.slice(0, 20);
  const gapSkills = (data?.aggregated ?? []).filter((e) => e.count < 3 && e.avgProficiency >= 3);

  if (isLoading) {
    return (
      <div className="p-6 space-y-4">
        <div className="h-8 shimmer-skeleton rounded w-64" />
        <div className="h-64 shimmer-skeleton rounded-xl" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="p-6">
        <div className="bg-red-50 border border-red-200 rounded-xl p-4 text-sm text-red-700">
          {error.message}
        </div>
      </div>
    );
  }

  return (
    <div className="p-6 pb-24 space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">Skills Analytics</h1>
          <p className="text-sm text-gray-500 mt-1">
            {data?.totalResources} active resources · {data?.totalSkillEntries} distinct skills
          </p>
        </div>
        <button
          type="button"
          onClick={exportXlsx}
          disabled={!data}
          className="px-3 py-1.5 text-sm rounded-lg border border-gray-200 text-gray-600 hover:bg-gray-50 disabled:opacity-50 transition-colors"
        >
          ↓ Export XLS
        </button>
      </div>

      {/* ── People Finder ──────────────────────────────────────────────────── */}
      <div className="bg-white rounded-xl border border-gray-200 p-5 space-y-4">
        <div className="flex items-center justify-between">
          <h2 className="text-sm font-semibold text-gray-800">People Finder</h2>
          <span className="text-xs text-gray-400">
            Find resources that match skill criteria
          </span>
        </div>

        {/* Rules */}
        <datalist id={datalistId}>
          {allSkillNames.map((s) => (
            <option key={s} value={s} />
          ))}
        </datalist>

        <div className="space-y-2">
          {rules.map((rule, idx) => (
            <div key={idx} className="flex items-center gap-2 flex-wrap">
              {/* AND / OR connector label */}
              {idx > 0 && (
                <button
                  type="button"
                  onClick={() => setOperator((op) => (op === "AND" ? "OR" : "AND"))}
                  className="w-12 text-center text-xs font-bold px-2 py-1.5 rounded-lg border border-brand-200 bg-brand-50 text-brand-700 hover:bg-brand-100 transition-colors shrink-0"
                >
                  {operator}
                </button>
              )}
              {idx === 0 && (
                <span className="w-12 text-center text-xs font-medium text-gray-400 shrink-0">
                  knows
                </span>
              )}

              {/* Skill input */}
              <input
                type="text"
                list={datalistId}
                placeholder="Skill name…"
                value={rule.skill}
                onChange={(e) => updateRule(idx, { skill: e.target.value })}
                className="flex-1 min-w-40 px-3 py-1.5 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
              />

              {/* Min proficiency selector */}
              <div className="flex items-center gap-1">
                <span className="text-xs text-gray-400 shrink-0">min.</span>
                <div className="flex rounded-lg overflow-hidden border border-gray-200">
                  {[1, 2, 3, 4, 5].map((lvl) => (
                    <button
                      key={lvl}
                      type="button"
                      title={PROFICIENCY_LABELS[lvl]}
                      onClick={() => updateRule(idx, { minProficiency: lvl })}
                      className={`px-2 py-1 text-xs font-medium transition-colors ${
                        rule.minProficiency === lvl
                          ? "bg-brand-600 text-white"
                          : "bg-white text-gray-500 hover:bg-gray-50"
                      }`}
                    >
                      {lvl}
                    </button>
                  ))}
                </div>
              </div>

              {/* Remove */}
              <button
                type="button"
                onClick={() => removeRule(idx)}
                className="text-gray-400 hover:text-red-500 transition-colors p-1"
              >
                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>
          ))}
        </div>

        {/* Add rule + chapter filter row */}
        <div className="flex flex-wrap items-center gap-3">
          <button
            type="button"
            onClick={addRule}
            className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg border border-dashed border-brand-300 text-brand-600 hover:bg-brand-50 transition-colors"
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
            </svg>
            Add skill rule
          </button>

          {rules.length > 1 && (
            <div className="flex items-center gap-1.5">
              <span className="text-xs text-gray-500">Match:</span>
              <button
                type="button"
                onClick={() => setOperator("AND")}
                className={`px-2.5 py-1 text-xs font-medium rounded-l-lg border transition-colors ${
                  operator === "AND"
                    ? "bg-brand-600 border-brand-600 text-white"
                    : "bg-white border-gray-200 text-gray-500 hover:bg-gray-50"
                }`}
              >
                All (AND)
              </button>
              <button
                type="button"
                onClick={() => setOperator("OR")}
                className={`px-2.5 py-1 text-xs font-medium rounded-r-lg border -ml-px transition-colors ${
                  operator === "OR"
                    ? "bg-brand-600 border-brand-600 text-white"
                    : "bg-white border-gray-200 text-gray-500 hover:bg-gray-50"
                }`}
              >
                Any (OR)
              </button>
            </div>
          )}

          {(data?.allChapters ?? []).length > 0 && (
            <div className="flex items-center gap-1.5 ml-auto">
              <span className="text-xs text-gray-500">Chapter:</span>
              <select
                value={peopleChapter}
                onChange={(e) => setPeopleChapter(e.target.value)}
                className="px-2 py-1.5 border border-gray-300 rounded-lg text-sm bg-white focus:outline-none focus:ring-2 focus:ring-brand-500"
              >
                <option value="">All chapters</option>
                {(data?.allChapters ?? []).map((c) => (
                  <option key={c} value={c}>{c}</option>
                ))}
              </select>
            </div>
          )}
        </div>

        {/* Results */}
        {activeRules.length > 0 && (
          <div className="border-t border-gray-100 pt-4">
            {peopleFetching ? (
              <div className="text-sm text-gray-400 animate-pulse">Searching…</div>
            ) : peopleResults && peopleResults.length === 0 ? (
              <p className="text-sm text-gray-400 italic">No resources match these criteria.</p>
            ) : peopleResults && peopleResults.length > 0 ? (
              <>
                <p className="text-xs text-gray-500 mb-3">
                  {peopleResults.length} resource{peopleResults.length !== 1 ? "s" : ""} found
                </p>
                <div className="space-y-2">
                  {peopleResults.map((person) => (
                    <div
                      key={person.id}
                      className="flex items-start gap-3 p-3 rounded-lg bg-gray-50 hover:bg-gray-100 transition-colors"
                    >
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2 flex-wrap">
                          <a
                            href={`/resources/${person.id}`}
                            className="text-sm font-medium text-gray-900 hover:text-brand-600 transition-colors"
                          >
                            {person.displayName}
                          </a>
                          {person.chapter && (
                            <span className="text-xs px-2 py-0.5 rounded-full bg-gray-200 text-gray-700 dark:bg-gray-600 dark:text-gray-100">
                              {person.chapter}
                            </span>
                          )}
                        </div>
                        <div className="flex flex-wrap gap-1.5 mt-1.5">
                          {person.matchedSkills.map((s) => (
                            <span
                              key={s.skill}
                              className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full border ${proficiencyClasses(s.proficiency)}`}
                            >
                              {s.skill}
                              <span className="font-semibold">{s.proficiency}</span>
                            </span>
                          ))}
                        </div>
                      </div>
                      <a
                        href={`/resources/${person.id}`}
                        className="text-xs text-brand-600 hover:underline shrink-0 mt-0.5"
                      >
                        View →
                      </a>
                    </div>
                  ))}
                </div>
              </>
            ) : null}
          </div>
        )}
      </div>

      {/* ── Skill table filters ────────────────────────────────────────────── */}
      <div className="flex flex-wrap gap-3 items-center">
        {/* Fuzzy search */}
        <div className="relative">
          <svg
            className="absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z" />
          </svg>
          <input
            type="text"
            placeholder="Search skills…"
            value={skillSearch}
            onChange={(e) => setSkillSearch(e.target.value)}
            className="pl-8 pr-3 py-2 border border-gray-300 rounded-lg text-sm bg-white focus:outline-none focus:ring-2 focus:ring-brand-500 w-52"
          />
        </div>

        <select
          value={categoryFilter}
          onChange={(e) => setCategoryFilter(e.target.value)}
          className="px-3 py-2 border border-gray-300 rounded-lg text-sm bg-white focus:outline-none focus:ring-2 focus:ring-brand-500"
        >
          <option value="">All Categories</option>
          {(data?.categories ?? []).map((c) => (
            <option key={c} value={c}>{c}</option>
          ))}
        </select>

        <label className="flex items-center gap-2 text-sm text-gray-600">
          Min. resources:
          <input
            type="number"
            min={1}
            max={50}
            value={minCount}
            onChange={(e) => setMinCount(Math.max(1, parseInt(e.target.value, 10) || 1))}
            className="w-16 px-2 py-1.5 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </label>

        <span className="text-sm text-gray-400">{filtered.length} skills shown</span>

        {(skillSearch || categoryFilter || minCount > 1) && (
          <button
            type="button"
            onClick={() => { setSkillSearch(""); setCategoryFilter(""); setMinCount(1); }}
            className="text-xs text-brand-600 hover:underline"
          >
            Clear filters
          </button>
        )}
      </div>

      {/* Top 20 Skills Bar Chart */}
      {top20.length > 0 && (
        <div className="bg-white rounded-xl border border-gray-200 p-5">
          <h2 className="text-sm font-semibold text-gray-800 mb-4">Top Skills by Resource Count</h2>
          <SkillDistributionChart data={top20} />
          <p className="text-xs text-gray-400 mt-2">Bar color = average proficiency (light → dark = low → high)</p>
        </div>
      )}

      {/* Skills Gap */}
      {gapSkills.length > 0 && (
        <div className="bg-white rounded-xl border border-gray-200 p-5">
          <h2 className="text-sm font-semibold text-gray-800 mb-3">
            Skills Gap
            <span className="ml-2 text-xs font-normal text-gray-400">high proficiency, few practitioners (&lt;3)</span>
          </h2>
          <div className="flex flex-wrap gap-2">
            {gapSkills.map((e) => (
              <button
                key={e.skill}
                type="button"
                onClick={() => {
                  setRules((prev) => [...prev, { skill: e.skill, minProficiency: 3 }]);
                  window.scrollTo({ top: 0, behavior: "smooth" });
                }}
                title="Add to People Finder"
                className="inline-flex items-center gap-1.5 px-3 py-1 text-sm rounded-full bg-red-50 text-red-700 border border-red-200 hover:bg-red-100 transition-colors"
              >
                {e.skill}
                <span className="text-xs opacity-70">{e.count} person{e.count !== 1 ? "s" : ""}</span>
              </button>
            ))}
          </div>
          <p className="text-xs text-gray-400 mt-2">Click a skill to add it to the People Finder above.</p>
        </div>
      )}

      {/* Skills Table */}
      <div className="bg-white rounded-xl border border-gray-200 overflow-hidden">
        <table className="w-full text-sm">
          <thead className="bg-gray-50 border-b border-gray-200">
            <tr>
              <SortableColumnHeader label="Skill" field="skill" sortField={skillSortField} sortDir={skillSortDir} onSort={skillToggle} />
              <SortableColumnHeader label="Category" field="category" sortField={skillSortField} sortDir={skillSortDir} onSort={skillToggle} />
              <SortableColumnHeader label="Resources" field="count" sortField={skillSortField} sortDir={skillSortDir} onSort={skillToggle} align="right" />
              <SortableColumnHeader label="Avg Prof." field="avgProficiency" sortField={skillSortField} sortDir={skillSortDir} onSort={skillToggle} align="right" />
              <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Chapters</th>
              <th className="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">Find</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-100">
            {sortedSkills.map((e) => (
              <tr key={e.skill} className="hover:bg-gray-50">
                <td className="px-4 py-2.5 font-medium text-gray-900">{e.skill}</td>
                <td className="px-4 py-2.5 text-gray-500">{e.category}</td>
                <td className="px-4 py-2.5 text-right text-gray-700">{e.count}</td>
                <td className="px-4 py-2.5 text-right">
                  <ProficiencyBadge value={e.avgProficiency} />
                </td>
                <td className="px-4 py-2.5 text-gray-400 text-xs">{e.chapters.join(", ") || "—"}</td>
                <td className="px-4 py-2.5 text-center">
                  <button
                    type="button"
                    title="Add to People Finder"
                    onClick={() => {
                      setRules((prev) => [...prev, { skill: e.skill, minProficiency: 1 }]);
                      window.scrollTo({ top: 0, behavior: "smooth" });
                    }}
                    className="text-gray-400 hover:text-brand-600 transition-colors"
                  >
                    <svg className="w-4 h-4 inline" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
                    </svg>
                  </button>
                </td>
              </tr>
            ))}
            {sortedSkills.length === 0 && (
              <tr>
                <td colSpan={6} className="text-center py-10 text-gray-400 text-sm">
                  No skills found matching the filters.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
