import React from "react";
import { Link, router } from "@inertiajs/react";
import {
    ArrowLeft,
    Check,
    CheckCircle2,
    Loader2,
    Save,
    ShieldCheck,
    X,
} from "lucide-react";
import { Card, PageHeader, Button, Badge } from "../../components/ui";

type Menu = { key: string; label: string };
type Matrix = Record<string, Record<string, boolean>>;

const roleLabel: Record<string, string> = {
    super_admin: "Super Admin",
    manager: "Manager",
    supervisor: "Supervisor",
    sales: "Sales",
    admin_pengiriman: "Admin Pengiriman",
    admin_penagihan: "Admin Penagihan",
    pengiriman: "Pengiriman",
    penagihan: "Penagihan",
};
const roleTone: Record<string, string> = {
    manager: "orange",
    supervisor: "orange",
    sales: "blue",
    admin_pengiriman: "green",
    admin_penagihan: "green",
    pengiriman: "slate",
    penagihan: "slate",
};

export default function Permission({
    roles,
    menus,
    matrix,
    capabilities = [],
    capabilityMatrix = {},
}: {
    roles: string[];
    menus: Menu[];
    matrix: Matrix;
    capabilities?: Menu[];
    capabilityMatrix?: Matrix;
}) {
    const [state, setState] = React.useState<Matrix>(matrix);
    const [capState, setCapState] = React.useState<Matrix>(capabilityMatrix);
    const [busy, setBusy] = React.useState(false);
    const [saved, setSaved] = React.useState(false);
    const [dirty, setDirty] = React.useState(false);

    const toggle = (role: string, key: string) => {
        setState((prev) => ({
            ...prev,
            [role]: { ...prev[role], [key]: !prev[role]?.[key] },
        }));
        setSaved(false);
        setDirty(true);
    };

    const toggleCapability = (role: string, key: string) => {
        setCapState((prev) => ({
            ...prev,
            [role]: { ...prev[role], [key]: !prev[role]?.[key] },
        }));
        setSaved(false);
        setDirty(true);
    };

    const toggleAllForRole = (role: string, value: boolean) => {
        const next: Record<string, boolean> = {};
        menus.forEach((m) => (next[m.key] = value));
        setState((prev) => ({ ...prev, [role]: next }));
        setSaved(false);
        setDirty(true);
    };

    const toggleAllForMenu = (menuKey: string, value: boolean) => {
        setState((prev) => {
            const next: Matrix = { ...prev };
            roles.forEach((role) => {
                next[role] = { ...next[role], [menuKey]: value };
            });
            return next;
        });
        setSaved(false);
        setDirty(true);
    };

    const toggleAllGlobal = (value: boolean) => {
        const next: Matrix = {};
        roles.forEach((role) => {
            next[role] = {};
            menus.forEach((m) => (next[role][m.key] = value));
        });
        setState(next);
        setSaved(false);
        setDirty(true);
    };

    const submit = () => {
        setBusy(true);
        setSaved(false);

        const permissions: Record<string, string[]> = {};
        roles.forEach((role) => {
            permissions[role] = menus
                .filter((m) => state[role]?.[m.key])
                .map((m) => m.key);
        });

        const capabilitiesPayload: Record<string, string[]> = {};
        roles.forEach((role) => {
            capabilitiesPayload[role] = capabilities
                .filter((c) => capState[role]?.[c.key])
                .map((c) => c.key);
        });

        router.put(
            "/settings/permissions",
            { permissions, capabilities: capabilitiesPayload },
            {
                preserveScroll: true,
                onSuccess: () => {
                    setBusy(false);
                    setSaved(true);
                    setDirty(false);
                },
                onError: () => setBusy(false),
            },
        );
    };

    return (
        <div className="p-7">
            <PageHeader
                title="Permission"
                description="Atur menu apa saja yang bisa diakses tiap role."
                action={
                    <Link
                        href="/settings"
                        className="inline-flex items-center gap-1.5 rounded-xl border border-slate-200 bg-white px-3.5 py-2 text-xs font-bold text-slate-600 hover:bg-slate-50"
                    >
                        <ArrowLeft size={15} />
                        Kembali ke Settings
                    </Link>
                }
            />

            <Card className="p-6">
                <div className="flex flex-wrap items-start justify-between gap-4">
                    <div className="flex items-start gap-3">
                        <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-[#e9fbf7] text-[#0b7668]">
                            <ShieldCheck size={18} />
                        </div>
                        <div>
                            <h2 className="font-black">Matrix Akses Menu</h2>
                            <p className="mt-1 text-xs leading-5 text-slate-500">
                                Centang menu yang boleh dilihat oleh
                                masing-masing role.{" "}
                                <span className="font-semibold text-slate-600">
                                    Super Admin
                                </span>{" "}
                                selalu punya akses penuh dan tidak tampil di
                                daftar ini. Perubahan baru berlaku setelah
                                tombol &quot;Simpan Perubahan&quot; ditekan.
                            </p>
                        </div>
                    </div>
                    <div className="flex shrink-0 items-center gap-1.5">
                        <Button
                            variant="outline"
                            size="sm"
                            onClick={() => toggleAllGlobal(true)}
                        >
                            Centang Semua
                        </Button>
                        <Button
                            variant="outline"
                            size="sm"
                            onClick={() => toggleAllGlobal(false)}
                        >
                            Kosongkan Semua
                        </Button>
                    </div>
                </div>

                <div className="mt-6 overflow-x-auto">
                    <table className="w-full min-w-205 border-collapse text-sm">
                        <thead>
                            <tr>
                                <th className="sticky left-0 z-10 w-56 min-w-55 bg-white p-2 pb-3 text-left text-xs font-bold uppercase tracking-wide text-slate-400">
                                    Menu
                                </th>
                                {roles.map((role) => (
                                    <th
                                        key={role}
                                        className="p-2 pb-3 text-center"
                                    >
                                        <div className="flex flex-col items-center gap-1.5">
                                            <Badge
                                                tone={roleTone[role] ?? "slate"}
                                            >
                                                {roleLabel[role] ?? role}
                                            </Badge>
                                            <div className="flex items-center gap-1">
                                                <button
                                                    type="button"
                                                    onClick={() =>
                                                        toggleAllForRole(
                                                            role,
                                                            true,
                                                        )
                                                    }
                                                    className="text-[10px] font-semibold text-[#0b7668] hover:underline"
                                                >
                                                    Semua
                                                </button>
                                                <span className="text-[10px] text-slate-300">
                                                    /
                                                </span>
                                                <button
                                                    type="button"
                                                    onClick={() =>
                                                        toggleAllForRole(
                                                            role,
                                                            false,
                                                        )
                                                    }
                                                    className="text-[10px] font-semibold text-slate-400 hover:underline"
                                                >
                                                    Tidak ada
                                                </button>
                                            </div>
                                        </div>
                                    </th>
                                ))}
                            </tr>
                        </thead>
                        <tbody>
                            {menus.map((menu, idx) => (
                                <tr
                                    key={menu.key}
                                    className={
                                        idx % 2 === 0 ? "bg-slate-50/60" : ""
                                    }
                                >
                                    <td className="sticky left-0 z-10 bg-inherit p-2.5 text-xs font-semibold text-slate-700">
                                        <div className="flex items-center justify-between gap-2">
                                            <span>{menu.label}</span>
                                            <span className="flex items-center gap-1">
                                                <button
                                                    type="button"
                                                    title={`Centang "${menu.label}" untuk semua role`}
                                                    onClick={() =>
                                                        toggleAllForMenu(
                                                            menu.key,
                                                            true,
                                                        )
                                                    }
                                                    className="text-[10px] font-semibold text-[#0b7668] hover:underline"
                                                >
                                                    Semua
                                                </button>
                                                <span className="text-[10px] text-slate-300">
                                                    /
                                                </span>
                                                <button
                                                    type="button"
                                                    title={`Kosongkan "${menu.label}" untuk semua role`}
                                                    onClick={() =>
                                                        toggleAllForMenu(
                                                            menu.key,
                                                            false,
                                                        )
                                                    }
                                                    className="text-[10px] font-semibold text-slate-400 hover:underline"
                                                >
                                                    Tidak ada
                                                </button>
                                            </span>
                                        </div>
                                    </td>
                                    {roles.map((role) => {
                                        const allowed =
                                            !!state[role]?.[menu.key];
                                        return (
                                            <td
                                                key={role}
                                                className="p-2.5 text-center"
                                            >
                                                <button
                                                    type="button"
                                                    aria-pressed={allowed}
                                                    aria-label={`${menu.label} untuk ${roleLabel[role] ?? role}`}
                                                    onClick={() =>
                                                        toggle(role, menu.key)
                                                    }
                                                    className={
                                                        "mx-auto grid h-7 w-7 place-items-center rounded-lg border transition " +
                                                        (allowed
                                                            ? "border-[#18b89a] bg-[#18b89a] text-white"
                                                            : "border-slate-200 bg-white text-slate-300 hover:border-slate-300")
                                                    }
                                                >
                                                    {allowed ? (
                                                        <Check size={14} />
                                                    ) : (
                                                        <X size={14} />
                                                    )}
                                                </button>
                                            </td>
                                        );
                                    })}
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>

                <div className="mt-6 flex items-center gap-3 border-t border-slate-100 pt-5">
                    <Button onClick={submit} disabled={busy || !dirty}>
                        {busy ? (
                            <Loader2 size={15} className="mr-2 animate-spin" />
                        ) : (
                            <Save size={15} className="mr-2" />
                        )}
                        Simpan Perubahan
                    </Button>
                    {saved && (
                        <span className="inline-flex items-center gap-1.5 text-xs font-bold text-emerald-600">
                            <CheckCircle2 size={15} />
                            Tersimpan.
                        </span>
                    )}
                </div>
            </Card>

            {capabilities.length > 0 && (
                <Card className="mt-5 p-6">
                    <div className="flex items-start gap-3">
                        <div className="grid h-10 w-10 shrink-0 place-items-center rounded-xl bg-[#e9fbf7] text-[#0b7668]">
                            <ShieldCheck size={18} />
                        </div>
                        <div>
                            <h2 className="font-black">Kemampuan Khusus</h2>
                            <p className="mt-1 text-xs leading-5 text-slate-500">
                                Atur aksi spesifik yang boleh dilakukan
                                masing-masing role, di luar akses menu biasa
                                (mis. siapa yang boleh mengubah status pada
                                Visit).{" "}
                                <span className="font-semibold text-slate-600">
                                    Super Admin
                                </span>{" "}
                                selalu punya akses penuh dan tidak tampil di
                                daftar ini.
                            </p>
                        </div>
                    </div>

                    <div className="mt-6 overflow-x-auto">
                        <table className="w-full min-w-205 border-collapse text-sm">
                            <thead>
                                <tr>
                                    <th className="sticky left-0 z-10 w-56 min-w-55 bg-white p-2 pb-3 text-left text-xs font-bold uppercase tracking-wide text-slate-400">
                                        Kemampuan
                                    </th>
                                    {roles.map((role) => (
                                        <th
                                            key={role}
                                            className="p-2 pb-3 text-center"
                                        >
                                            <Badge
                                                tone={roleTone[role] ?? "slate"}
                                            >
                                                {roleLabel[role] ?? role}
                                            </Badge>
                                        </th>
                                    ))}
                                </tr>
                            </thead>
                            <tbody>
                                {capabilities.map((cap, idx) => (
                                    <tr
                                        key={cap.key}
                                        className={
                                            idx % 2 === 0
                                                ? "bg-slate-50/60"
                                                : ""
                                        }
                                    >
                                        <td className="sticky left-0 z-10 bg-inherit p-2.5 text-xs font-semibold text-slate-700">
                                            {cap.label}
                                        </td>
                                        {roles.map((role) => {
                                            const allowed =
                                                !!capState[role]?.[cap.key];
                                            return (
                                                <td
                                                    key={role}
                                                    className="p-2.5 text-center"
                                                >
                                                    <button
                                                        type="button"
                                                        aria-pressed={allowed}
                                                        aria-label={`${cap.label} untuk ${roleLabel[role] ?? role}`}
                                                        onClick={() =>
                                                            toggleCapability(
                                                                role,
                                                                cap.key,
                                                            )
                                                        }
                                                        className={
                                                            "mx-auto grid h-7 w-7 place-items-center rounded-lg border transition " +
                                                            (allowed
                                                                ? "border-[#18b89a] bg-[#18b89a] text-white"
                                                                : "border-slate-200 bg-white text-slate-300 hover:border-slate-300")
                                                        }
                                                    >
                                                        {allowed ? (
                                                            <Check size={14} />
                                                        ) : (
                                                            <X size={14} />
                                                        )}
                                                    </button>
                                                </td>
                                            );
                                        })}
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>

                    <div className="mt-6 flex items-center gap-3 border-t border-slate-100 pt-5">
                        <Button onClick={submit} disabled={busy || !dirty}>
                            {busy ? (
                                <Loader2
                                    size={15}
                                    className="mr-2 animate-spin"
                                />
                            ) : (
                                <Save size={15} className="mr-2" />
                            )}
                            Simpan Perubahan
                        </Button>
                        {saved && (
                            <span className="inline-flex items-center gap-1.5 text-xs font-bold text-emerald-600">
                                <CheckCircle2 size={15} />
                                Tersimpan.
                            </span>
                        )}
                    </div>
                </Card>
            )}
        </div>
    );
}
