"use client";

import { useCallback, useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import { toast } from "sonner";
import { getApiErrorMessage } from "@/lib/api-error";
import ClientWorkspaceLayout from "@/features/client/client-workspace-layout";
import {
  disableOrgModule,
  enableOrgModule,
  fetchOrgModuleActivations,
  type OrgModuleRow,
} from "@/platform/api/modules-api";

const ACTIVE_STATES = new Set(["active", "enabled"]);

export default function OrgModulesAdmin() {
  return (
    <ClientWorkspaceLayout title="Apps & modules">
      {(ctx) => (
        <OrgModulesPanel
          orgKey={
            ctx.tenantApiKey === "me"
              ? ctx.tenantClientId || ""
              : ctx.effectiveClientKey
          }
        />
      )}
    </ClientWorkspaceLayout>
  );
}

function OrgModulesPanel({ orgKey }: { orgKey: string }) {
  const [rows, setRows] = useState<OrgModuleRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [busyId, setBusyId] = useState<string | null>(null);

  const load = useCallback(async () => {
    if (!orgKey) return;
    setLoading(true);
    try {
      const data = await fetchOrgModuleActivations(orgKey);
      setRows(data);
    } catch (e) {
      toast.error(getApiErrorMessage(e, "Failed to load modules"));
    } finally {
      setLoading(false);
    }
  }, [orgKey]);

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

  const toggle = async (row: OrgModuleRow, nextOn: boolean) => {
    try {
      setBusyId(row.moduleId);
      if (nextOn) {
        await enableOrgModule(orgKey, row.moduleId);
        toast.success(`${row.name} enabled`);
      } else {
        await disableOrgModule(orgKey, row.moduleId);
        toast.success(`${row.name} disabled`);
      }
      await load();
      window.dispatchEvent(new CustomEvent("nizamify:modules-changed"));
    } catch (e) {
      toast.error(getApiErrorMessage(e, "Could not update module"));
    } finally {
      setBusyId(null);
    }
  };

  if (loading) {
    return <p className="text-center text-gray-500 py-8">Loading modules…</p>;
  }

  const grouped = rows.reduce<Record<string, OrgModuleRow[]>>((acc, row) => {
    const key = row.category || "other";
    if (!acc[key]) acc[key] = [];
    acc[key].push(row);
    return acc;
  }, {});

  return (
    <div className="space-y-8">
      <p className="text-sm text-gray-600">
        Turn apps on or off for this business. Disabled apps are hidden from the sidebar and blocked on
        the API. Free apps activate immediately.
      </p>

      {Object.entries(grouped).map(([category, mods]) => (
        <section key={category} className="space-y-3">
          <h2 className="text-sm font-semibold uppercase tracking-wide text-gray-500">{category}</h2>
          <ul className="divide-y rounded-lg border bg-white">
            {mods.map((row) => {
              const isOn = ACTIVE_STATES.has(row.state);
              const isFree = row.defaultState === "free";
              return (
                <li
                  key={row.moduleId}
                  className="flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:justify-between"
                >
                  <div className="min-w-0 flex-1">
                    <p className="font-medium text-slate-900">{row.name}</p>
                    <p className="mt-1 text-sm text-gray-600">{row.description}</p>
                    <p className="mt-2 text-xs text-gray-500">
                      {isFree ? "Free tier" : `Billing: ${row.billingModes.join(", ")}`} · State:{" "}
                      <span className="font-medium capitalize">{row.state}</span>
                    </p>
                    {row.dependencies?.length ? (
                      <p className="mt-1 text-xs text-amber-700">
                        Requires: {row.dependencies.join(", ")}
                      </p>
                    ) : null}
                  </div>
                  <div className="flex items-center gap-3 shrink-0">
                    <Switch
                      checked={isOn}
                      disabled={busyId === row.moduleId}
                      onCheckedChange={(checked) => toggle(row, checked)}
                      aria-label={`Toggle ${row.name}`}
                    />
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      disabled={busyId === row.moduleId}
                      onClick={() => toggle(row, !isOn)}
                    >
                      {isOn ? "Disable" : "Enable"}
                    </Button>
                  </div>
                </li>
              );
            })}
          </ul>
        </section>
      ))}
    </div>
  );
}
