"use client";

import { useState } from "react";
import { Loader2, RotateCcw, X } from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useT } from "@/shared/i18n/client";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Badge } from "@/presentation/components/ui/badge";
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "@/presentation/components/ui/sheet";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/presentation/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/presentation/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/presentation/components/ui/table";
import type { CompanyEntitlements, EntitlementState, QuotaPeriod, SetOverridePayload } from "@/domain/entities/entitlement";
import type { SubscriptionPlan } from "@/domain/entities/subscription-plan";
import { CompanySubscriptionPanel } from "./company-subscription-panel";

type Target =
  | { kind: "capability"; key: string; label: string; state: EntitlementState; preview: boolean }
  | { kind: "quota"; key: string; label: string; limit: number | null; period: QuotaPeriod | null; periodic: boolean };

const STATE_CLASS: Record<EntitlementState, string> = {
  allow: "bg-green-100 text-green-800",
  preview: "bg-amber-100 text-amber-800",
  deny: "bg-slate-100 text-slate-600",
};

/**
 * A company's plan and its exceptions (SCRUM-353): change the plan, open or close a module
 * for this company only, raise a limit, give a consumed import back.
 */
export function CompanyEntitlementsSheet({ companyId, companyName, open, onOpenChange }: {
  companyId: number | null;
  companyName: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const t = useT();
  const container = useRepositories();
  const [search, setSearch] = useState("");
  const [target, setTarget] = useState<Target | null>(null);

  const { data, loading, refetch } = useApiQuery<CompanyEntitlements | null>(
    () => (companyId ? container.entitlementRepository.getCompany(companyId) : Promise.resolve(null)),
    { deps: [companyId, open], enabled: open && !!companyId }
  );

  const { data: plans } = useApiQuery<SubscriptionPlan[]>(
    () => container.subscriptionRepository.getPlans(),
    { deps: [open], enabled: open }
  );

  const removeOverride = useApiMutation(
    (key: string) => container.entitlementRepository.removeOverride(companyId!, key),
    { successMessage: t.entitlements.overrideRemoved, onSuccess: () => refetch() }
  );
  const resetUsage = useApiMutation(
    (key: string) => container.entitlementRepository.resetUsage(companyId!, key),
    { successMessage: t.entitlements.usageReset, onSuccess: () => refetch() }
  );

  const filter = (label: string, key: string) => !search || `${label} ${key}`.toLowerCase().includes(search.toLowerCase());
  const stateBadge = (state: EntitlementState) => <Badge className={STATE_CLASS[state]}>{t.entitlements.states[state]}</Badge>;
  // The day the admin picked (the stored date part): the end of that day in server time must
  // not read as the next day in the browser's time zone.
  const expiry = (iso: string | null) => (iso ? iso.slice(0, 10).split("-").reverse().join("/") : null);
  const current = data && data.company.id === companyId ? data : null;

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className="w-full sm:max-w-3xl overflow-y-auto">
        <SheetHeader>
          <SheetTitle>{t.entitlements.companyTitle(companyName)}</SheetTitle>
          <SheetDescription>{t.entitlements.companyHint}</SheetDescription>
        </SheetHeader>

        {loading && !current ? (
          <div className="flex justify-center py-10"><Loader2 className="w-6 h-6 animate-spin" /></div>
        ) : current && (
          <div className="space-y-6 px-4 pb-6">
            {/* The plan, its change with the month's proration, the cancellation (billing automation, part 2). */}
            <CompanySubscriptionPanel
              companyId={companyId!}
              currentPlan={current.company.plan ? { id: current.company.plan.id, name: current.company.plan.name } : null}
              plans={plans ?? []}
              onPlanChanged={() => refetch()}
            />
            <div className="flex flex-wrap items-center gap-3">
              <Input className="max-w-xs ml-auto" placeholder={t.entitlements.search} value={search} onChange={(e) => setSearch(e.target.value)} />
            </div>

            <div>
              <h3 className="text-sm font-semibold mb-2">{t.entitlements.capabilities}</h3>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t.entitlements.capabilities}</TableHead>
                    <TableHead>{t.entitlements.planState}</TableHead>
                    <TableHead>{t.entitlements.effective}</TableHead>
                    <TableHead>{t.entitlements.override}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {current.capabilities.filter((c) => filter(c.label, c.key)).map((c) => (
                    <TableRow key={c.key}>
                      <TableCell>
                        <div className="font-medium">{c.label}</div>
                        <div className="text-xs text-muted-foreground">{c.key}</div>
                      </TableCell>
                      <TableCell>{stateBadge(c.plan_state)}</TableCell>
                      <TableCell>{stateBadge(c.state)}</TableCell>
                      <TableCell>
                        <div className="flex items-center gap-1">
                          {c.override && (
                            <span className={`text-xs ${c.override.expired ? "line-through text-muted-foreground" : ""}`}
                              title={c.override.note ?? undefined}>
                              {c.override.state ? t.entitlements.states[c.override.state] : ""}
                              {c.override.expires_at ? ` · ${expiry(c.override.expires_at)}` : ""}
                              {c.override.expired ? ` (${t.entitlements.expired})` : ""}
                            </span>
                          )}
                          <Button variant="outline" size="sm" onClick={() => setTarget({ kind: "capability", key: c.key, label: c.label, state: c.override?.state ?? c.state, preview: c.preview })}>
                            {t.entitlements.setOverride}
                          </Button>
                          {c.override && (
                            <Button variant="ghost" size="icon" title={t.entitlements.removeOverride} onClick={() => removeOverride.mutate(c.key)}>
                              <X className="w-4 h-4" />
                            </Button>
                          )}
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>

            <div>
              <h3 className="text-sm font-semibold mb-2">{t.entitlements.quotas}</h3>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t.entitlements.quotas}</TableHead>
                    <TableHead>{t.entitlements.used}</TableHead>
                    <TableHead>{t.entitlements.planLimit}</TableHead>
                    <TableHead>{t.entitlements.override}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {current.quotas.filter((q) => filter(q.label, q.key)).map((q) => (
                    <TableRow key={q.key}>
                      <TableCell>
                        <div className="font-medium">{q.label}</div>
                        <div className="text-xs text-muted-foreground">{q.key}</div>
                      </TableCell>
                      <TableCell>
                        {q.counter === "setting"
                          ? (q.limit ?? "—")
                          : `${q.used ?? 0} / ${q.unlimited || q.limit === null ? "∞" : q.limit}`}
                        {q.period === "month" && <span className="text-xs text-muted-foreground"> · {t.entitlements.periods.month}</span>}
                      </TableCell>
                      <TableCell>{q.plan_limit ?? "∞"}</TableCell>
                      <TableCell>
                        <div className="flex items-center gap-1">
                          {q.override && (
                            <span className={`text-xs ${q.override.expired ? "line-through text-muted-foreground" : ""}`} title={q.override.note ?? undefined}>
                              {q.override.limit ?? "∞"}
                              {q.override.expires_at ? ` · ${expiry(q.override.expires_at)}` : ""}
                            </span>
                          )}
                          <Button variant="outline" size="sm" onClick={() => setTarget({
                            kind: "quota", key: q.key, label: q.label, limit: q.override?.limit ?? q.limit, period: q.override?.period ?? q.period, periodic: q.periodic,
                          })}>
                            {t.entitlements.setOverride}
                          </Button>
                          {q.override && (
                            <Button variant="ghost" size="icon" title={t.entitlements.removeOverride} onClick={() => removeOverride.mutate(q.key)}>
                              <X className="w-4 h-4" />
                            </Button>
                          )}
                          {q.counter === "ledger" && (q.used ?? 0) > 0 && (
                            <Button variant="ghost" size="icon" title={t.entitlements.resetUsage} onClick={() => resetUsage.mutate(q.key)}>
                              <RotateCcw className="w-4 h-4" />
                            </Button>
                          )}
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </div>
        )}

        <Dialog open={!!target} onOpenChange={(o) => !o && setTarget(null)}>
          <DialogContent className="max-w-md">
            <DialogHeader>
              <DialogTitle>{target ? t.entitlements.overrideTitle(target.label) : ""}</DialogTitle>
            </DialogHeader>
            {target && companyId && (
              <OverrideForm key={target.key} companyId={companyId} target={target}
                onClose={() => setTarget(null)} onSaved={() => { setTarget(null); refetch(); }} />
            )}
          </DialogContent>
        </Dialog>
      </SheetContent>
    </Sheet>
  );
}

/** One exception: a module's state, or a limit's ceiling (empty = none), with a note and an end date. */
function OverrideForm({ companyId, target, onClose, onSaved }: {
  companyId: number;
  target: Target;
  onClose: () => void;
  onSaved: () => void;
}) {
  const t = useT();
  const container = useRepositories();
  const [state, setState] = useState<EntitlementState>(target.kind === "capability" ? target.state : "allow");
  const [limit, setLimit] = useState(target.kind === "quota" && target.limit !== null ? String(target.limit) : "");
  const [period, setPeriod] = useState<QuotaPeriod>(target.kind === "quota" ? (target.period ?? "lifetime") : "lifetime");
  const [note, setNote] = useState("");
  const [expiresAt, setExpiresAt] = useState("");

  const save = useApiMutation(
    (payload: SetOverridePayload) => container.entitlementRepository.setOverride(companyId, target.key, payload),
    { successMessage: t.entitlements.overrideSaved, onSuccess: onSaved }
  );

  const submit = () => {
    const common = { note: note || null, expires_at: expiresAt || null };
    save.mutate(target.kind === "capability"
      ? { state, ...common }
      : { limit: limit.trim() === "" ? null : Number(limit), period: target.periodic ? period : null, ...common });
  };

  return (
    <div className="space-y-3">
      {target.kind === "capability" ? (
        <Select value={state} onValueChange={(v) => setState(v as EntitlementState)}>
          <SelectTrigger><SelectValue /></SelectTrigger>
          <SelectContent>
            {/* "Aperçu" only where the platform has a preview screen, as in the plan editor. */}
            {(["allow", "preview", "deny"] as EntitlementState[])
              .filter((s) => s !== "preview" || target.preview || state === "preview")
              .map((s) => (
                <SelectItem key={s} value={s}>{t.entitlements.states[s]}</SelectItem>
              ))}
          </SelectContent>
        </Select>
      ) : (
        <div className="flex gap-2">
          <Input type="number" min={0} placeholder={t.entitlements.unlimited} value={limit} onChange={(e) => setLimit(e.target.value)} />
          {target.periodic && (
            <Select value={period} onValueChange={(v) => setPeriod(v as QuotaPeriod)}>
              <SelectTrigger className="w-40"><SelectValue /></SelectTrigger>
              <SelectContent>
                <SelectItem value="lifetime">{t.entitlements.periods.lifetime}</SelectItem>
                <SelectItem value="month">{t.entitlements.periods.month}</SelectItem>
              </SelectContent>
            </Select>
          )}
        </div>
      )}
      <Input placeholder={t.entitlements.note} value={note} onChange={(e) => setNote(e.target.value)} />
      <div>
        <label className="text-xs text-muted-foreground">{t.entitlements.expiresAt}</label>
        <Input type="date" value={expiresAt} onChange={(e) => setExpiresAt(e.target.value)} />
      </div>
      <div className="flex justify-end gap-2">
        <Button variant="outline" onClick={onClose}>{t.entitlements.cancel}</Button>
        <Button onClick={submit} disabled={save.loading}>
          {save.loading && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
          {t.entitlements.save}
        </Button>
      </div>
    </div>
  );
}
