"use client";

import Link from "next/link";
import { useMemo, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Kpi, KpiStrip } from "@/components/ui/kpi";
import { EmptyState } from "@/components/ui/empty-state";
import { useLocalStorage } from "@/lib/hooks/use-local-storage";
import {
  compareToBenchmark,
  getBenchmarkForRole,
  type Band,
  type CompBenchmark,
  type PayType,
} from "@/lib/hr/comp-benchmarks";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import type { Employee } from "@/lib/sag/employees-seed";
import { formatCurrency } from "@/lib/utils";

// ──────────────────────────────────────────────────────────────────────────
// LocalStorage keys
// ──────────────────────────────────────────────────────────────────────────

const KEY_EMPLOYEES = "sag.hr.employees";

// ──────────────────────────────────────────────────────────────────────────
// Filter types
// ──────────────────────────────────────────────────────────────────────────

type EntityFilter = "all" | string;
type PayTypeFilter = "all" | PayType;
type BandFilter = "all" | Band;

// ──────────────────────────────────────────────────────────────────────────
// Band display config
// ──────────────────────────────────────────────────────────────────────────

const BAND_LABEL: Record<Band, string> = {
  below_p25: "Below p25",
  at_p25_p50: "p25 – p50",
  at_p50_p75: "p50 – p75",
  above_p75: "Above p75",
  unknown: "No benchmark",
};

/**
 * Tailwind class chips for each band — kept inline rather than relying on
 * Badge variants because we need a four-step semantic ramp (red → amber
 * → green → blue) plus a neutral. Matches the same Badge primitive
 * height / radius for visual consistency.
 */
const BAND_CHIP_CLASS: Record<Band, string> = {
  below_p25:
    "border-transparent bg-red-100 text-red-900 dark:bg-red-900/30 dark:text-red-100",
  at_p25_p50:
    "border-transparent bg-yellow-100 text-yellow-900 dark:bg-yellow-900/30 dark:text-yellow-100",
  at_p50_p75:
    "border-transparent bg-green-100 text-green-900 dark:bg-green-900/30 dark:text-green-100",
  above_p75:
    "border-transparent bg-blue-100 text-blue-900 dark:bg-blue-900/30 dark:text-blue-100",
  unknown:
    "border-transparent bg-muted text-muted-foreground",
};

// ──────────────────────────────────────────────────────────────────────────
// Main component
// ──────────────────────────────────────────────────────────────────────────

export function CompBenchmarks() {
  const [employees] = useLocalStorage<Employee[]>(KEY_EMPLOYEES, []);

  const [entityFilter, setEntityFilter] = useState<EntityFilter>("all");
  const [payTypeFilter, setPayTypeFilter] = useState<PayTypeFilter>("all");
  const [bandFilter, setBandFilter] = useState<BandFilter>("all");

  // Compute every active employee's benchmark row. Inactive / terminated
  // people aren't relevant to a comp-fairness review — exclude them up front.
  const allRows: CompBenchmark[] = useMemo(() => {
    return employees
      .filter((e) => e.status === "Active")
      .map((e) => toBenchmarkRow(e))
      .filter((r): r is CompBenchmark => r !== null);
  }, [employees]);

  // KPI strip uses the unfiltered roster so the headline numbers don't
  // shift around when the user narrows the table view.
  const kpis = useMemo(() => {
    let withBenchmark = 0;
    let missing = 0;
    let belowP25 = 0;
    let aboveP75 = 0;
    for (const r of allRows) {
      if (r.market) {
        withBenchmark += 1;
        if (r.band === "below_p25") belowP25 += 1;
        else if (r.band === "above_p75") aboveP75 += 1;
      } else {
        missing += 1;
      }
    }
    return { withBenchmark, missing, belowP25, aboveP75 };
  }, [allRows]);

  const filteredRows = useMemo(() => {
    const filtered = allRows.filter((r) => {
      if (entityFilter !== "all" && r.entitySlug !== entityFilter) return false;
      if (payTypeFilter !== "all" && r.payType !== payTypeFilter) return false;
      if (bandFilter !== "all") {
        const effective: Band = r.band ?? "unknown";
        if (effective !== bandFilter) return false;
      }
      return true;
    });

    // Sort by ratio ascending so the lowest-paid relative to market are at
    // the top — i.e. the rows most likely to need a raise. Unmatched rows
    // (no benchmark, ratio undefined) sink to the bottom.
    return filtered.slice().sort((a, b) => {
      const ra = a.ratio;
      const rb = b.ratio;
      if (ra === undefined && rb === undefined) {
        return a.employeeName.localeCompare(b.employeeName);
      }
      if (ra === undefined) return 1;
      if (rb === undefined) return -1;
      return ra - rb;
    });
  }, [allRows, entityFilter, payTypeFilter, bandFilter]);

  function resetFilters() {
    setEntityFilter("all");
    setPayTypeFilter("all");
    setBandFilter("all");
  }

  const hasFiltersApplied =
    entityFilter !== "all" || payTypeFilter !== "all" || bandFilter !== "all";

  return (
    <div className="space-y-6">
      {/* ─── KPI strip ──────────────────────────────────────────────────── */}
      <KpiStrip cols={4}>
        <Kpi label="Employees benchmarked" value={String(kpis.withBenchmark)} />
        <Kpi
          label="Missing benchmark"
          value={String(kpis.missing)}
          tone={kpis.missing > 0 ? "amber" : "neutral"}
        />
        <Kpi
          label="Below p25"
          value={String(kpis.belowP25)}
          tone={kpis.belowP25 > 0 ? "rose" : "neutral"}
        />
        <Kpi
          label="Above p75"
          value={String(kpis.aboveP75)}
          tone={kpis.aboveP75 > 0 ? "violet" : "neutral"}
        />
      </KpiStrip>

      {/* ─── Filters ────────────────────────────────────────────────────── */}
      <Card>
        <CardContent className="p-4 flex flex-wrap items-end gap-3">
          <div className="flex flex-col gap-1">
            <label className="section-label">
              Entity
            </label>
            <select
              value={entityFilter}
              onChange={(e) => setEntityFilter(e.target.value)}
              className="h-9 rounded-md border border-input bg-background px-3 text-sm min-w-[14rem]"
            >
              <option value="all">All entities</option>
              {ALL_ORGANIZATIONS.map((o) => (
                <option key={o.slug} value={o.slug}>
                  {o.emoji} {o.name}
                </option>
              ))}
            </select>
          </div>

          <div className="flex flex-col gap-1">
            <label className="section-label">
              Pay type
            </label>
            <select
              value={payTypeFilter}
              onChange={(e) => setPayTypeFilter(e.target.value as PayTypeFilter)}
              className="h-9 rounded-md border border-input bg-background px-3 text-sm"
            >
              <option value="all">All pay types</option>
              <option value="hourly">Hourly</option>
              <option value="salary">Salary</option>
            </select>
          </div>

          <div className="flex flex-col gap-1">
            <label className="section-label">
              Band
            </label>
            <select
              value={bandFilter}
              onChange={(e) => setBandFilter(e.target.value as BandFilter)}
              className="h-9 rounded-md border border-input bg-background px-3 text-sm"
            >
              <option value="all">All bands</option>
              <option value="below_p25">Below p25</option>
              <option value="at_p25_p50">p25 – p50</option>
              <option value="at_p50_p75">p50 – p75</option>
              <option value="above_p75">Above p75</option>
              <option value="unknown">No benchmark</option>
            </select>
          </div>

          <span className="text-xs text-muted-foreground tabular-nums">
            {filteredRows.length} of {allRows.length}
          </span>

          {hasFiltersApplied && (
            <Button variant="ghost" size="sm" className="ml-auto" onClick={resetFilters}>
              Reset filters
            </Button>
          )}
        </CardContent>
      </Card>

      {/* ─── Table ──────────────────────────────────────────────────────── */}
      <Card>
        <CardContent className="p-5">
          <div className="flex items-center justify-between mb-3">
            <h2 className="text-sm font-semibold">Roles vs. NC market</h2>
            <span className="section-label">
              Active employees · sorted by ratio (outliers first)
            </span>
          </div>

          {allRows.length === 0 ? (
            <EmptyState
              icon="📊"
              title="No active employees yet"
              description={
                <>
                  Add hires in the{" "}
                  <Link href="/app/hr" className="underline hover:text-foreground">
                    HR directory
                  </Link>{" "}
                  to see comp benchmark comparisons here.
                </>
              }
              className="border-0 shadow-none"
              size="compact"
            />
          ) : filteredRows.length === 0 ? (
            <p className="text-xs text-muted-foreground py-6 text-center">
              No employees match the current filters.
            </p>
          ) : (
            <div className="overflow-x-auto">
              <table className="w-full text-sm min-w-[720px]">
                <thead className="section-label border-b">
                  <tr>
                    <th className="px-2 py-2 text-left">Employee</th>
                    <th className="px-2 py-2 text-left">Entity</th>
                    <th className="px-2 py-2 text-left">Role</th>
                    <th className="px-2 py-2 text-left">Pay type</th>
                    <th className="px-2 py-2 text-right">Current</th>
                    <th className="px-2 py-2 text-right">p25</th>
                    <th className="px-2 py-2 text-right">p50</th>
                    <th className="px-2 py-2 text-right">p75</th>
                    <th className="px-2 py-2 text-right">Ratio</th>
                    <th className="px-2 py-2 text-left">Band</th>
                    <th className="px-2 py-2 text-right">&nbsp;</th>
                  </tr>
                </thead>
                <tbody>
                  {filteredRows.map((r) => {
                    const org = ALL_ORGANIZATIONS.find(
                      (o) => o.slug === r.entitySlug
                    );
                    const band: Band = r.band ?? "unknown";
                    return (
                      <tr key={r.employeeId} className="border-b last:border-0">
                        <td className="px-2 py-2 font-medium">{r.employeeName}</td>
                        <td className="px-2 py-2 text-xs text-muted-foreground">
                          {org ? `${org.emoji} ${org.name}` : r.entitySlug}
                        </td>
                        <td className="px-2 py-2 text-sm">{r.role}</td>
                        <td className="px-2 py-2 text-xs text-muted-foreground capitalize">
                          {r.payType}
                        </td>
                        <td className="px-2 py-2 text-right tabular-nums font-medium">
                          {fmtPay(r.current, r.payType)}
                        </td>
                        <td className="px-2 py-2 text-right tabular-nums text-muted-foreground">
                          {r.market ? fmtPay(r.market.p25, r.payType) : "—"}
                        </td>
                        <td className="px-2 py-2 text-right tabular-nums text-muted-foreground">
                          {r.market ? fmtPay(r.market.p50, r.payType) : "—"}
                        </td>
                        <td className="px-2 py-2 text-right tabular-nums text-muted-foreground">
                          {r.market ? fmtPay(r.market.p75, r.payType) : "—"}
                        </td>
                        <td className="px-2 py-2 text-right tabular-nums">
                          {r.ratio !== undefined ? (
                            <span className={ratioClass(band)}>
                              {fmtRatio(r.ratio)}
                            </span>
                          ) : (
                            <span className="text-muted-foreground">—</span>
                          )}
                        </td>
                        <td className="px-2 py-2">
                          <span
                            className={`inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold ${BAND_CHIP_CLASS[band]}`}
                          >
                            {BAND_LABEL[band]}
                          </span>
                        </td>
                        <td className="px-2 py-2 text-right">
                          <Link
                            href="/app/hr"
                            className="text-xs text-muted-foreground hover:text-foreground hover:underline whitespace-nowrap"
                          >
                            Open employee record &rarr;
                          </Link>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </CardContent>
      </Card>

      {/* ─── Footnote ───────────────────────────────────────────────────── */}
      <Card className="border-dashed">
        <CardContent className="p-4 text-xs text-muted-foreground space-y-1.5">
          <div>
            <strong className="text-foreground">Sources —</strong> Benchmarks
            compiled from BLS OEWS NC May 2024 plus published industry
            surveys. Tipped roles exclude gratuities. Update{" "}
            <code className="text-foreground">SEED_BENCHMARKS</code> at{" "}
            <code className="text-foreground">
              src/lib/hr/comp-benchmarks.ts
            </code>{" "}
            when new data lands.
          </div>
          <div>
            <strong className="text-foreground">Read-only —</strong> This view
            does not mutate employee records. Adjust pay in the{" "}
            <Link href="/app/hr" className="underline hover:text-foreground">
              HR directory
            </Link>{" "}
            and re-open this page to see the band change.
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Helpers
// ──────────────────────────────────────────────────────────────────────────

/**
 * Project an employee into a `CompBenchmark` row. Returns `null` when the
 * employee has no usable comp shape (missing role, or a comp type that
 * isn't hourly/salary — commission/equity/other can't be benchmarked on
 * a single dollar figure).
 */
function toBenchmarkRow(e: Employee): CompBenchmark | null {
  if (!e.role) return null;
  if (e.compType !== "hourly" && e.compType !== "salary") return null;
  const current = Number.isFinite(e.compAmount) ? (e.compAmount as number) : 0;
  const payType: PayType = e.compType;

  const market = getBenchmarkForRole(e.role);

  // Only compare when the benchmark's pay type matches the employee's,
  // otherwise the percentile numbers aren't on the same axis. (Treat a
  // mismatch as "no benchmark matched" — the same UX as a missing alias.)
  if (market && market.payType === payType && current > 0) {
    const { ratio, band } = compareToBenchmark(e, market);
    return {
      employeeId: e.id,
      employeeName: e.fullName,
      entitySlug: e.organizationSlug,
      role: e.role,
      payType,
      current,
      market,
      ratio,
      band,
    };
  }

  // Either no match at all, or a pay-type mismatch we can't band against.
  return {
    employeeId: e.id,
    employeeName: e.fullName,
    entitySlug: e.organizationSlug,
    role: e.role,
    payType,
    current,
    market: null,
    band: "unknown",
  };
}

function fmtPay(amount: number, payType: PayType): string {
  if (payType === "salary") {
    // Display salaries with no cents and a compact thousands separator —
    // matches how the HR directory shows annual figures.
    return new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: "USD",
      maximumFractionDigits: 0,
    }).format(amount);
  }
  return `${formatCurrency(amount)}/hr`;
}

function fmtRatio(ratio: number): string {
  return `${ratio.toFixed(2)}x`;
}

function ratioClass(band: Band): string {
  switch (band) {
    case "below_p25":
      return "text-red-700 dark:text-red-400 font-semibold";
    case "at_p25_p50":
      return "text-yellow-700 dark:text-yellow-400";
    case "at_p50_p75":
      return "text-green-700 dark:text-green-400";
    case "above_p75":
      return "text-blue-700 dark:text-blue-400 font-semibold";
    case "unknown":
      return "text-muted-foreground";
  }
}


