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

import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Spinner } from "@/components/ui/spinner";
import { useAuth } from "@/context/AuthContext";
import { useAuthStore } from "@/store/authStore";
import { apiGet, apiPost } from "@/lib/api";
import type { HotelLedgerRow, HotelPointAction, HotelPointRule } from "@/lib/hotel-staff-types";

type RowEdit = Record<string, { points: string; isEnabled: boolean }>;

export function LoyaltyPointsPage() {
  const { canManageLoyalty, canViewFinanceLedger } = useAuth();
  const selectedPropertyId = useAuthStore((s) => s.selectedPropertyId);
  const [catalog, setCatalog] = useState<HotelPointAction[]>([]);
  const [rules, setRules] = useState<HotelPointRule[]>([]);
  const [loading, setLoading] = useState(true);
  const [savingId, setSavingId] = useState<string | null>(null);
  const [edit, setEdit] = useState<RowEdit>({});
  const [ledger, setLedger] = useState<HotelLedgerRow[]>([]);
  const [ledgerLoading, setLedgerLoading] = useState(false);
  const [ledgerError, setLedgerError] = useState<string | null>(null);

  const ruleByActionId = useMemo(() => {
    const m = new Map<string, HotelPointRule>();
    for (const r of rules) m.set(r.actionId, r);
    return m;
  }, [rules]);

  const loadLedger = useCallback(async () => {
    if (!canViewFinanceLedger) return;
    setLedgerLoading(true);
    setLedgerError(null);
    try {
      const res = await apiGet<{ data: HotelLedgerRow[] }>("/loyalty/ledger");
      setLedger(res.data ?? []);
    } catch (e) {
      setLedger([]);
      setLedgerError(e instanceof Error ? e.message : "Could not load ledger");
    } finally {
      setLedgerLoading(false);
    }
  }, [canViewFinanceLedger, selectedPropertyId]);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [c, r] = await Promise.all([
        apiGet<HotelPointAction[]>("/loyalty/catalog"),
        apiGet<HotelPointRule[]>("/loyalty/rules"),
      ]);
      setCatalog(c.filter((a) => a.isActive));
      setRules(r);
      const next: RowEdit = {};
      for (const a of c) {
        const existing = r.find((x) => x.actionId === a.id);
        next[a.id] = {
          points: String(existing?.points ?? 0),
          isEnabled: existing?.isEnabled ?? true,
        };
      }
      setEdit(next);
    } finally {
      setLoading(false);
    }
  }, [selectedPropertyId]);

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

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

  async function saveRow(actionId: string) {
    if (!canManageLoyalty) return;
    const row = edit[actionId];
    if (!row) return;
    const points = Math.max(0, parseInt(row.points, 10) || 0);
    setSavingId(actionId);
    try {
      await apiPost("/loyalty/rules", {
        actionId,
        points,
        isEnabled: row.isEnabled,
      });
      await load();
    } finally {
      setSavingId(null);
    }
  }

  if (loading) {
    return (
      <div className="flex min-h-[320px] items-center justify-center">
        <Spinner size={32} />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold tracking-tight">Point rules</h1>
        <p className="text-muted-foreground">
          Set how many points guests earn per action 
        </p>
      </div>

      <Card className="rounded-2xl">
        <CardHeader>
          <CardTitle className="text-base">Actions</CardTitle>
        </CardHeader>
        <CardContent>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Code</TableHead>
                <TableHead>Label</TableHead>
                <TableHead className="w-28">Points</TableHead>
                <TableHead className="w-32">Enabled</TableHead>
                <TableHead className="w-28" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {catalog.map((a) => {
                const e = edit[a.id] ?? { points: "0", isEnabled: true };
                const hasRule = ruleByActionId.has(a.id);
                return (
                  <TableRow key={a.id}>
                    <TableCell className="font-mono text-xs">{a.code}</TableCell>
                    <TableCell>{a.label}</TableCell>
                    <TableCell>
                      <Input
                        type="number"
                        min={0}
                        className="h-9 w-24"
                        disabled={!canManageLoyalty}
                        value={e.points}
                        onChange={(ev) =>
                          setEdit((prev) => ({
                            ...prev,
                            [a.id]: { ...e, points: ev.target.value },
                          }))
                        }
                      />
                    </TableCell>
                    <TableCell>
                      <label className="flex items-center gap-2 text-sm">
                        <input
                          type="checkbox"
                          disabled={!canManageLoyalty}
                          checked={e.isEnabled}
                          onChange={(ev) =>
                            setEdit((prev) => ({
                              ...prev,
                              [a.id]: { ...e, isEnabled: ev.target.checked },
                            }))
                          }
                        />
                        {hasRule ? "On" : "New"}
                      </label>
                    </TableCell>
                    <TableCell>
                      {canManageLoyalty && (
                        <Button
                          size="sm"
                          variant="secondary"
                          disabled={savingId === a.id}
                          onClick={() => void saveRow(a.id)}
                        >
                          {savingId === a.id ? "…" : "Save"}
                        </Button>
                      )}
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
          {!catalog.length && (
            <p className="py-8 text-center text-muted-foreground text-sm">
              No point actions in catalog
            </p>
          )}
        </CardContent>
      </Card>

      <Card className="rounded-2xl">
        <CardHeader className="flex flex-row flex-wrap items-center justify-between gap-2">
          <CardTitle className="text-base">Finance: point ledger</CardTitle>
          {canViewFinanceLedger ? (
            <Button
              type="button"
              size="sm"
              variant="outline"
              disabled={ledgerLoading}
              onClick={() => void loadLedger()}
            >
              {ledgerLoading ? "Refreshing…" : "Refresh"}
            </Button>
          ) : null}
        </CardHeader>
        <CardContent className="text-sm">
          {!canViewFinanceLedger ? (
            <p className="text-muted-foreground">
              Full property ledger is visible to finance and admin roles only.
            </p>
          ) : ledgerError ? (
            <p className="text-destructive">{ledgerError}</p>
          ) : ledgerLoading && !ledger.length ? (
            <div className="flex justify-center py-8">
              <Spinner size={28} />
            </div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>When</TableHead>
                  <TableHead>Guest</TableHead>
                  <TableHead className="text-right">Δ</TableHead>
                  <TableHead>Reason</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {ledger.map((row) => (
                  <TableRow key={row.id}>
                    <TableCell className="whitespace-nowrap text-xs text-muted-foreground">
                      {new Date(row.createdAt).toLocaleString()}
                    </TableCell>
                    <TableCell className="text-xs">
                      <div>{row.user?.name ?? row.userId}</div>
                      <div className="text-muted-foreground">{row.user?.email ?? ""}</div>
                    </TableCell>
                    <TableCell className="text-right font-mono text-xs">{row.delta}</TableCell>
                    <TableCell className="text-xs">{row.reason}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
          {canViewFinanceLedger && !ledgerLoading && !ledger.length && !ledgerError ? (
            <p className="py-6 text-center text-muted-foreground text-sm">No ledger rows yet.</p>
          ) : null}
        </CardContent>
      </Card>
    </div>
  );
}
