"use client";

import { useEffect, useMemo, useState } from "react";

import { useLocale } from "@/components/providers/locale-provider";
import { EmptyState, StatCard } from "@/components/shared/ops-primitives";
import { formatCurrencyAmount, formatDecimal, formatQuantity } from "@/lib/formatters";
import type { ApiErrorResponse } from "@/types/api";
import type { LotListItem } from "@/types/lot";

type SummaryRow = {
  key: string;
  warehouse: string;
  grade: string;
  unit_code: string;
  lot_count: number;
  available_qty: number;
  estimated_value: number;
  avg_aging_days: number;
};

type StockSummaryReportClientProps = {
  currencyCode: string;
};

export function StockSummaryReportClient({ currencyCode }: StockSummaryReportClientProps) {
  const { locale } = useLocale();
  const [lots, setLots] = useState<LotListItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [warehouseFilter, setWarehouseFilter] = useState("ALL");
  const [gradeFilter, setGradeFilter] = useState("ALL");
  const [statusFilter, setStatusFilter] = useState("ACTIVE");

  async function loadLots() {
    setLoading(true);
    setError(null);
    try {
      const response = await fetch("/api/v1/lots", { cache: "no-store" });
      const payload = (await response.json()) as { data: LotListItem[] } | ApiErrorResponse;

      if (!response.ok || !("data" in payload)) {
        throw new Error("message" in payload ? payload.message : locale === "id" ? "Gagal memuat data ringkasan stok." : "Failed to load stock summary data.");
      }

      setLots(payload.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : locale === "id" ? "Gagal memuat data ringkasan stok." : "Failed to load stock summary data.");
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void loadLots();
  }, []);

  const warehouseOptions = useMemo(
    () => ["ALL", ...new Set(lots.map((lot) => lot.warehouse))],
    [lots]
  );
  const gradeOptions = useMemo(
    () => ["ALL", ...new Set(lots.map((lot) => lot.grade))],
    [lots]
  );

  const filteredLots = useMemo(() => {
    return lots.filter((lot) => {
      if (warehouseFilter !== "ALL" && lot.warehouse !== warehouseFilter) return false;
      if (gradeFilter !== "ALL" && lot.grade !== gradeFilter) return false;
      if (statusFilter !== "ALL" && lot.status !== statusFilter) return false;
      return true;
    });
  }, [gradeFilter, lots, statusFilter, warehouseFilter]);

  const summaryRows = useMemo<SummaryRow[]>(() => {
    const grouped = new Map<string, SummaryRow>();

    filteredLots.forEach((lot) => {
      const grade = lot.grade;
      const key = [lot.warehouse, grade, lot.unit_code].join("::");
      const existing = grouped.get(key);
      const estimatedValue = lot.available_qty * lot.unit_cost;

      if (existing) {
        existing.lot_count += 1;
        existing.available_qty += lot.available_qty;
        existing.estimated_value += estimatedValue;
        existing.avg_aging_days += lot.aging_days;
        return;
      }

      grouped.set(key, {
        key,
        warehouse: lot.warehouse,
        grade,
        unit_code: lot.unit_code,
        lot_count: 1,
        available_qty: lot.available_qty,
        estimated_value: estimatedValue,
        avg_aging_days: lot.aging_days
      });
    });

    return Array.from(grouped.values())
      .map((row) => ({
        ...row,
        avg_aging_days: row.lot_count > 0 ? row.avg_aging_days / row.lot_count : 0
      }))
      .sort((a, b) => b.estimated_value - a.estimated_value);
  }, [filteredLots]);

  const totals = useMemo(() => {
    const activeLots = filteredLots.filter((lot) => lot.status === "ACTIVE");
    const agedLots = filteredLots.filter((lot) => lot.aging_days >= 30);
    const unitCodes = Array.from(new Set(filteredLots.map((lot) => lot.unit_code).filter(Boolean)));

    return {
      lot_count: filteredLots.length,
      active_count: activeLots.length,
      available_qty: filteredLots.reduce((sum, lot) => sum + lot.available_qty, 0),
      estimated_value: filteredLots.reduce((sum, lot) => sum + lot.available_qty * lot.unit_cost, 0),
      aged_count: agedLots.length,
      unit_code: unitCodes.length === 1 ? unitCodes[0] : null
    };
  }, [filteredLots]);

  return (
    <section className="space-y-6">
      <div className="ops-card p-6">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
          <div>
            <p className="ops-overline">{locale === "id" ? "Pelaporan operasional" : "Operational reporting"}</p>
            <h2 className="mt-2 text-[32px] font-semibold tracking-tight text-ink">{locale === "id" ? "Laporan ringkasan stok" : "Stock summary report"}</h2>
            <p className="mt-3 max-w-3xl text-[14px] leading-7 text-slate-600">
              {locale === "id"
                ? "Ringkasan ini dihitung langsung dari lot persediaan aktif yang sudah ada. Owner dan operasional sudah bisa melihat posisi stok per gudang dan grade tanpa menunggu modul laporan terpisah."
                : "This summary is calculated directly from existing active inventory lots. Owners and operations can already see stock positions by warehouse and grade without waiting for a separate reporting module."}
            </p>
          </div>
          <button type="button" onClick={() => void loadLots()} className="ops-btn-secondary" disabled={loading}>
            {locale === "id" ? "Refresh laporan" : "Refresh report"}
          </button>
        </div>

        <div className="mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
          <FilterSelect label={locale === "id" ? "Gudang" : "Warehouse"} value={warehouseFilter} onChange={setWarehouseFilter} options={warehouseOptions} locale={locale} />
          <FilterSelect label={locale === "id" ? "Grade" : "Grade"} value={gradeFilter} onChange={setGradeFilter} options={gradeOptions} locale={locale} />
          <FilterSelect label={locale === "id" ? "Status" : "Status"} value={statusFilter} onChange={setStatusFilter} options={["ACTIVE", "ALL", "HOLD", "CLOSED"]} locale={locale} />
        </div>

        {error ? (
          <div className="mt-5 rounded border border-ember/30 bg-ember/10 px-4 py-3 text-sm text-ember">{error}</div>
        ) : null}
      </div>

      <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-5">
        <StatCard label={locale === "id" ? "Lot terfilter" : "Filtered lots"} value={String(totals.lot_count)} hint={locale === "id" ? "Jumlah lot setelah filter" : "Lot count after filters"} />
        <StatCard label={locale === "id" ? "Lot aktif" : "Active lots"} value={String(totals.active_count)} hint={locale === "id" ? "Lot berstatus ACTIVE" : "Lots with ACTIVE status"} tone="teal" />
        <StatCard label={locale === "id" ? "Qty tersedia" : "Available qty"} value={formatQuantity(totals.available_qty, locale, totals.unit_code)} hint={totals.unit_code ? (locale === "id" ? "Total qty tersedia" : "Total available qty") : (locale === "id" ? "Total qty tersedia · mixed units" : "Total available qty · mixed units")} />
        <StatCard label={locale === "id" ? "Estimasi nilai" : "Estimated value"} value={formatCurrencyAmount(totals.estimated_value, locale, currencyCode, 0)} hint={locale === "id" ? "Qty tersedia x unit cost" : "Available qty × unit cost"} />
        <StatCard label={locale === "id" ? "Umur 30+ hari" : "Aging 30+ days"} value={String(totals.aged_count)} hint={locale === "id" ? "Perlu perhatian rotasi stok" : "Needs stock-rotation attention"} tone="warning" />
      </div>

      <div className="ops-table-shell">
        <div className="ops-section-head">
          <div>
              <p className="ops-title">{locale === "id" ? "Ringkasan stok per grup" : "Grouped stock summary"}</p>
              <p className="ops-copy">{locale === "id" ? "Agregasi stok per gudang dan grade." : "Stock aggregation by warehouse and grade."}</p>
            </div>
            <div className="ops-chip-muted">{summaryRows.length} {locale === "id" ? "grup" : "groups"}</div>
          </div>

        {loading ? (
          <div className="px-6 py-8 text-sm text-slate-500">{locale === "id" ? "Memuat ringkasan stok..." : "Loading stock summary..."}</div>
        ) : summaryRows.length === 0 ? (
          <EmptyState
            title={locale === "id" ? "Tidak ada data untuk filter ini" : "No data for this filter"}
            copy={locale === "id" ? "Ubah filter atau pastikan transaksi penerimaan sudah membentuk lot persediaan." : "Change the filters or make sure receiving transactions have created inventory lots."}
          />
        ) : (
          <div className="overflow-x-auto">
            <table className="ops-table">
              <thead>
                <tr>
                  <th>{locale === "id" ? "Gudang" : "Warehouse"}</th>
                  <th>{locale === "id" ? "Grade" : "Grade"}</th>
                  <th>{locale === "id" ? "Jumlah Lot" : "Lot Count"}</th>
                  <th>{locale === "id" ? "Qty Tersedia" : "Available Qty"}</th>
                  <th>{locale === "id" ? "Estimasi Nilai" : "Estimated Value"}</th>
                  <th>{locale === "id" ? "Rata-rata Umur" : "Avg Aging"}</th>
                </tr>
              </thead>
              <tbody>
                {summaryRows.map((row) => (
                  <tr key={row.key}>
                    <td className="font-medium text-ink">{row.warehouse}</td>
                    <td>{row.grade}</td>
                    <td>{row.lot_count}</td>
                    <td>{formatQuantity(row.available_qty, locale, row.unit_code)}</td>
                    <td>{formatCurrencyAmount(row.estimated_value, locale, currencyCode, 0)}</td>
                    <td>{formatDecimal(row.avg_aging_days, locale)} {locale === "id" ? "hari" : "days"}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </section>
  );
}

function FilterSelect({
  label,
  value,
  onChange,
  options,
  locale
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  options: string[];
  locale: string;
}) {
  return (
    <label>
      <span className="ops-label">{label}</span>
      <select value={value} onChange={(event) => onChange(event.target.value)} className="ops-select">
        {options.map((option) => (
          <option key={option} value={option}>
            {option === "ALL" ? (locale === "id" ? "Semua" : "All") : option}
          </option>
        ))}
      </select>
    </label>
  );
}
