"use client";

import { useReducer, useCallback, useEffect } from "react";
import {
  exportTaxReport,
  exportTaxByState,
  type TaxOrderRow,
  type TaxByStateRow,
} from "@/lib/reports-export";
import {
  getTaxSummaryAction,
  getTaxableOrdersAction,
  type TaxSummaryData,
} from "@/actions/tax";
import { AdminButton, AdminFilterTabs } from "@/components/admin/design-system";

type DatePreset = "month" | "quarter" | "this_year" | "custom";

type DateRange = { start: string; end: string };

function buildRange(preset: DatePreset, customStart?: string, customEnd?: string): DateRange {
  const now = new Date();
  const toDateStr = (d: Date) => d.toISOString().slice(0, 10);
  const today = toDateStr(now);

  switch (preset) {
    case "month": {
      const start = new Date(now.getFullYear(), now.getMonth(), 1);
      return { start: toDateStr(start), end: today };
    }
    case "quarter": {
      const q = Math.floor(now.getMonth() / 3);
      const start = new Date(now.getFullYear(), q * 3, 1);
      return { start: toDateStr(start), end: today };
    }
    case "this_year": {
      const start = new Date(now.getFullYear(), 0, 1);
      return { start: toDateStr(start), end: today };
    }
    case "custom":
      return { start: customStart ?? today, end: customEnd ?? today };
  }
}

function downloadCSV(csv: string, filename: string) {
  const blob = new Blob([csv], { type: "text/csv" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

function quarterLabel(start: string): string {
  const s = new Date(start + "T00:00:00");
  const q = Math.floor(s.getMonth() / 3) + 1;
  return `Q${q} ${s.getFullYear()}`;
}

type TaxSummaryDataLocal = TaxSummaryData;

function SummaryCard({
  label,
  value,
  prefix,
  suffix,
  highlight,
}: {
  label: string;
  value: number;
  prefix?: string;
  suffix?: string;
  highlight?: boolean;
}) {
  return (
    <div className={`rounded-xl border px-4 py-4 ${highlight ? "border-amber-300 bg-amber-900/30" : "border-zinc-800 bg-zinc-900"}`}>
      <p className="text-xs font-medium uppercase tracking-wide text-zinc-500">{label}</p>
      <p className={`mt-1 text-2xl font-semibold ${highlight ? "text-amber-700" : "text-zinc-100"}`}>
        {prefix ?? ""}{typeof value === "number" ? value.toLocaleString(undefined, { maximumFractionDigits: 2 }) : value}{suffix ?? ""}
      </p>
    </div>
  );
}

function ExportBtn({ onClick }: { label?: string; onClick: () => void }) {
  return (
    <AdminButton
      onClick={onClick}
      variant="secondary"
      size="sm"
    >
      Export CSV
    </AdminButton>
  );
}

function ReportTable({ headers, rows, renderRow }: {
  headers: string[];
  rows: unknown[];
  renderRow: (row: unknown, i: number) => React.ReactNode;
}) {
  return (
    <div className="overflow-x-auto rounded-xl border border-zinc-800 bg-zinc-900">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-zinc-800 bg-slate-50">
            {headers.map((h) => (
              <th key={h} className="px-3 py-2 text-left text-xs font-medium uppercase tracking-wide text-zinc-500">
                {h}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 ? (
            <tr>
              <td colSpan={headers.length} className="px-3 py-6 text-center text-slate-400">
                No data
              </td>
            </tr>
          ) : (
            rows.map((row, i) => renderRow(row, i))
          )}
        </tbody>
      </table>
    </div>
  );
}

const TABS = [
  { value: "summary", label: "Tax Summary" },
  { value: "orders", label: "Taxable Orders" },
];

type State = {
  preset: DatePreset;
  customStart: string;
  customEnd: string;
  selectedBrandId: string;
  activeTab: string;
  summary: TaxSummaryDataLocal | null;
  orders: TaxOrderRow[];
  loading: boolean;
  error: string | null;
};

type Action =
  | { type: "SET_PRESET"; preset: DatePreset }
  | { type: "SET_CUSTOM_START"; value: string }
  | { type: "SET_CUSTOM_END"; value: string }
  | { type: "SET_BRAND"; brandId: string }
  | { type: "SET_TAB"; tab: string }
  | { type: "SET_SUMMARY"; data: TaxSummaryDataLocal }
  | { type: "SET_ORDERS"; data: TaxOrderRow[] }
  | { type: "RESET_DATA" }
  | { type: "SET_LOADING"; value: boolean }
  | { type: "SET_ERROR"; error: string | null };

const initialState: State = {
  preset: "quarter",
  customStart: "",
  customEnd: "",
  selectedBrandId: "",
  activeTab: "summary",
  summary: null,
  orders: [],
  loading: false,
  error: null,
};

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_PRESET":
      return { ...state, preset: action.preset };
    case "SET_CUSTOM_START":
      return { ...state, customStart: action.value };
    case "SET_CUSTOM_END":
      return { ...state, customEnd: action.value };
    case "SET_BRAND":
      return { ...state, selectedBrandId: action.brandId };
    case "SET_TAB":
      return { ...state, activeTab: action.tab };
    case "SET_SUMMARY":
      return { ...state, summary: action.data };
    case "SET_ORDERS":
      return { ...state, orders: action.data };
    case "RESET_DATA":
      return { ...state, summary: null, orders: [] };
    case "SET_LOADING":
      return { ...state, loading: action.value };
    case "SET_ERROR":
      return { ...state, error: action.error };
  }
}

export default function TaxDashboard({
  brands,
  initialBrandId,
  isPlatformAdmin,
}: {
  brands: { id: string; name: string }[];
  initialBrandId: string | null;
  isPlatformAdmin: boolean;
}) {
  const [state, dispatch] = useReducer(reducer, {
    ...initialState,
    selectedBrandId: initialBrandId ?? "",
  });

  const range: DateRange = buildRange(state.preset, state.customStart, state.customEnd);

  // Year is read from the clock inline at the rendering site so we never
  // need to mirror it into React state. This sidesteps the "fake event
  // handler" anti-pattern (no useEffect that watches a clock and sets
  // state) and avoids any hydration mismatch — the "YYYY YTD" label is
  // only ever shown in the browser, not during SSR.
  const currentYear = new Date().getFullYear();

  const fetchTaxSummary = useCallback(async () => {
    if (!state.selectedBrandId) return;
    dispatch({ type: "SET_LOADING", value: true });
    dispatch({ type: "SET_ERROR", error: null });

    try {
      const result = await getTaxSummaryAction({
        brandId: state.selectedBrandId,
        startDate: range.start,
        endDate: range.end,
      });
      if (!result.success) throw new Error(result.error);
      dispatch({ type: "SET_SUMMARY", data: result.data });
    } catch (err) {
      dispatch({ type: "SET_ERROR", error: err instanceof Error ? err.message : "Failed to load tax summary" });
    } finally {
      dispatch({ type: "SET_LOADING", value: false });
    }
  }, [state.selectedBrandId, range.start, range.end]);

  const fetchTaxableOrders = useCallback(async () => {
    if (!state.selectedBrandId) return;
    dispatch({ type: "SET_LOADING", value: true });
    dispatch({ type: "SET_ERROR", error: null });

    try {
      const result = await getTaxableOrdersAction({
        brandId: state.selectedBrandId,
        startDate: range.start,
        endDate: range.end,
      });
      if (!result.success) throw new Error(result.error);
      dispatch({ type: "SET_ORDERS", data: result.data });
    } catch (err) {
      dispatch({ type: "SET_ERROR", error: err instanceof Error ? err.message : "Failed to load orders" });
    } finally {
      dispatch({ type: "SET_LOADING", value: false });
    }
  }, [state.selectedBrandId, range.start, range.end]);

  const fetchForCurrentTab = useCallback(async () => {
    if (!state.selectedBrandId) return;
    if (state.activeTab === "summary") {
      await fetchTaxSummary();
    } else {
      await fetchTaxableOrders();
    }
  }, [state.selectedBrandId, state.activeTab, fetchTaxSummary, fetchTaxableOrders]);

  // Initial fetch on mount — runs once when the dashboard first renders.
  // Subsequent fetches happen inside the change handlers below, so we
  // never have to watch state changes from a useEffect.
  useEffect(() => {
    if (!state.selectedBrandId) return;
    void fetchForCurrentTab();
    // selectedBrandId + activeTab are stable for this initial-load path;
    // re-runs only on mount.
  }, [state.selectedBrandId, fetchForCurrentTab]);

  function handlePresetChange(p: DatePreset) {
    dispatch({ type: "SET_PRESET", preset: p });
    if (p !== "custom") {
      void fetchForCurrentTab();
    }
  }

  function handleCustomDatesChange() {
    if (state.preset === "custom") {
      void fetchForCurrentTab();
    }
  }

  function handleBrandChange(brandId: string) {
    dispatch({ type: "SET_BRAND", brandId });
    dispatch({ type: "RESET_DATA" });
    void fetchForCurrentTab();
  }

  function handleTabChange(tab: string) {
    dispatch({ type: "SET_TAB", tab });
    void fetchForCurrentTab();
  }

  function handleExportCSV() {
    if (state.activeTab === "summary" && state.summary) {
      const rows: TaxByStateRow[] = state.summary.tax_by_state.map((s) => ({
        state: s.state,
        total_tax: s.total_tax,
        gross_sales: s.gross_sales,
        order_count: s.order_count,
      }));
      const csv = exportTaxByState(rows);
      downloadCSV(csv, `tax-by-state-${range.start}.csv`);
    } else if (state.activeTab === "orders" && state.orders.length > 0) {
      const csv = exportTaxReport(state.orders);
      downloadCSV(csv, `taxable-orders-${range.start}.csv`);
    }
  }

  const effectiveRate = state.summary && state.summary.total_gross_sales > 0
    ? (state.summary.total_tax_collected / state.summary.total_gross_sales) * 100
    : 0;

  return (
    <div className="space-y-6">
      {state.error && (
        <div className="rounded-xl bg-red-900/30 border border-red-200 px-4 py-3 text-sm text-red-400">
          {state.error}
        </div>
      )}

      <FilterBar
        preset={state.preset}
        customStart={state.customStart}
        customEnd={state.customEnd}
        selectedBrandId={state.selectedBrandId}
        loading={state.loading}
        isPlatformAdmin={isPlatformAdmin}
        brands={brands}
        rangeStart={range.start}
        rangeEnd={range.end}
        currentYear={currentYear}
        onPresetChange={handlePresetChange}
        onCustomStartChange={(value) => {
          dispatch({ type: "SET_CUSTOM_START", value });
          handleCustomDatesChange();
        }}
        onCustomEndChange={(value) => {
          dispatch({ type: "SET_CUSTOM_END", value });
          handleCustomDatesChange();
        }}
        onBrandChange={handleBrandChange}
        onRefresh={fetchForCurrentTab}
      />

      <AdminFilterTabs
        activeTab={state.activeTab}
        onTabChange={handleTabChange}
        tabs={TABS}
        size="md"
        showCounts={false}
      />

      {state.activeTab === "summary" && (
        <SummaryTab
          summary={state.summary}
          loading={state.loading}
          effectiveRate={effectiveRate}
          onExport={handleExportCSV}
        />
      )}

      {state.activeTab === "orders" && (
        <OrdersTab orders={state.orders} onExport={handleExportCSV} />
      )}
    </div>
  );
}

type FilterBarProps = {
  preset: DatePreset;
  customStart: string;
  customEnd: string;
  selectedBrandId: string;
  loading: boolean;
  isPlatformAdmin: boolean;
  brands: { id: string; name: string }[];
  rangeStart: string;
  rangeEnd: string;
  currentYear: number;
  onPresetChange: (p: DatePreset) => void;
  onCustomStartChange: (value: string) => void;
  onCustomEndChange: (value: string) => void;
  onBrandChange: (brandId: string) => void;
  onRefresh: () => void | Promise<void>;
};

function FilterBar({
  preset,
  customStart,
  customEnd,
  selectedBrandId,
  loading,
  isPlatformAdmin,
  brands,
  rangeStart,
  rangeEnd,
  currentYear,
  onPresetChange,
  onCustomStartChange,
  onCustomEndChange,
  onBrandChange,
  onRefresh,
}: FilterBarProps) {
  return (
    <div className="flex flex-wrap items-center gap-3 rounded-xl border border-[var(--admin-border)] bg-[var(--admin-card-bg)] px-5 py-4">
      <div className="flex gap-1">
        {(["month", "quarter", "this_year", "custom"] as DatePreset[]).map((p) => (
          <AdminButton
            key={p}
            onClick={() => onPresetChange(p)}
            variant={preset === p ? "primary" : "secondary"}
            size="sm"
          >
            {p === "month" ? "This Month" : p === "quarter" ? "This Quarter" : p === "this_year" ? "This Year" : "Custom"}
          </AdminButton>
        ))}
      </div>

      {preset === "custom" && (
        <div className="flex gap-2 items-center">
          <input aria-label="Date"
            type="date"
            value={customStart}
            onChange={(e) => onCustomStartChange(e.target.value)}
            className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs"
          />
          <span className="text-slate-400 text-xs">to</span>
          <input aria-label="Date"
            type="date"
            value={customEnd}
            onChange={(e) => onCustomEndChange(e.target.value)}
            className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs"
          />
        </div>
      )}

      {isPlatformAdmin && (
        <select aria-label="Select"
          value={selectedBrandId}
          onChange={(e) => onBrandChange(e.target.value)}
          className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs"
        >
          <option value="">All Brands</option>
          {brands.map((b) => (
            <option key={b.id} value={b.id}>{b.name}</option>
          ))}
        </select>
      )}

      <AdminButton
        onClick={() => void onRefresh()}
        disabled={loading || !selectedBrandId}
        variant="primary"
        size="sm"
        isLoading={loading}
      >
        Refresh
      </AdminButton>

      <span className="ml-auto text-xs text-zinc-500">
        {preset === "quarter" ? quarterLabel(rangeStart) :
         preset === "this_year" ? `${currentYear} YTD` :
         `${rangeStart} → ${rangeEnd}`}
      </span>
    </div>
  );
}

type SummaryTabProps = {
  summary: TaxSummaryDataLocal | null;
  loading: boolean;
  effectiveRate: number;
  onExport: () => void;
};

function SummaryTab({ summary, loading, effectiveRate, onExport }: SummaryTabProps) {
  return (
    <div className="space-y-4">
      {summary && (
        <>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
            <SummaryCard
              label="Total Tax Collected"
              value={summary.total_tax_collected}
              prefix="$"
              highlight
            />
            <SummaryCard
              label="Total Gross Sales"
              value={summary.total_gross_sales}
              prefix="$"
            />
            <SummaryCard
              label="Effective Tax Rate"
              value={effectiveRate}
              suffix="%"
            />
            <SummaryCard
              label="Taxable Orders"
              value={summary.order_count}
            />
          </div>

          <div className="flex items-center justify-between">
            <h3 className="text-sm font-semibold text-zinc-300">Tax by State</h3>
            {summary.tax_by_state.length > 0 && (
              <ExportBtn label="Export CSV" onClick={onExport} />
            )}
          </div>
          <ReportTable
            headers={["State", "Total Tax", "Gross Sales", "Orders", "Eff. Rate"]}
            rows={summary.tax_by_state}
            renderRow={(row) => {
              const r = row as { state: string; total_tax: number; gross_sales: number; order_count: number };
              const rate = r.gross_sales > 0 ? (r.total_tax / r.gross_sales) * 100 : 0;
              return (
                <tr key={r.state} className="border-t border-slate-100 hover:bg-zinc-800">
                  <td className="px-3 py-2 font-medium text-zinc-100">{r.state}</td>
                  <td className="px-3 py-2 text-right text-amber-700 font-medium">${r.total_tax.toFixed(2)}</td>
                  <td className="px-3 py-2 text-right">${r.gross_sales.toFixed(2)}</td>
                  <td className="px-3 py-2 text-right">{r.order_count}</td>
                  <td className="px-3 py-2 text-right text-zinc-500">{rate.toFixed(2)}%</td>
                </tr>
              );
            }}
          />
        </>
      )}

      {!summary && !loading && (
        <div className="rounded-xl border border-zinc-800 bg-zinc-900 px-6 py-12 text-center text-slate-400">
          Click Refresh to load tax summary
        </div>
      )}
    </div>
  );
}

type OrdersTabProps = {
  orders: TaxOrderRow[];
  onExport: () => void;
};

function OrdersTab({ orders, onExport }: OrdersTabProps) {
  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between">
        <h3 className="text-sm font-semibold text-zinc-300">Taxable Orders</h3>
        {orders.length > 0 && (
          <ExportBtn label="Export CSV" onClick={onExport} />
        )}
      </div>
      <ReportTable
        headers={["Order ID", "Date", "Customer", "City", "State", "Taxable Amt", "Tax", "Rate", "Location"]}
        rows={orders}
        renderRow={(row) => {
          const r = row as TaxOrderRow;
          return (
            <tr key={r.order_id} className="border-t border-slate-100 hover:bg-zinc-800">
              <td className="px-3 py-2 font-mono text-xs text-zinc-400">{r.order_id.slice(0, 8)}</td>
              <td className="px-3 py-2 text-zinc-400">{r.date}</td>
              <td className="px-3 py-2 font-medium text-zinc-100">{r.customer_name}</td>
              <td className="px-3 py-2 text-zinc-400">{r.city}</td>
              <td className="px-3 py-2 text-zinc-400">{r.state}</td>
              <td className="px-3 py-2 text-right">${Number(r.taxable_amount).toFixed(2)}</td>
              <td className="px-3 py-2 text-right text-amber-700 font-medium">${Number(r.tax_amount).toFixed(2)}</td>
              <td className="px-3 py-2 text-right text-zinc-500">{Number(r.tax_rate).toFixed(4)}</td>
              <td className="px-3 py-2 text-zinc-500 text-xs">{r.tax_location}</td>
            </tr>
          );
        }}
      />
    </div>
  );
}