"use client";

import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import { DatabaseIcon, PencilIcon, PlusIcon, Trash2Icon } from "lucide-react";
import { PharmaciesApi } from "@/lib/api";
import { PanelError } from "@/components/medora/errors";
import { MedoraPageHeader } from "@/components/medora/page-header";
import { ListTable, Tag, type Col } from "@/components/medora/record-lists";
import { RowActions } from "@/components/medora/row-actions";
import { ConfirmDialog } from "@/components/medora/confirm-dialog";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Field, FieldDescription, FieldLabel, FieldLegend, FieldSet } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select";
import { toast } from "@/components/ui/toast";
import { Loading } from "@/components/medora/loading";

/**
 * SuperAdmin → Pharmacies (plan O: the SuperAdmin pages on the design). Every tenant, with its contact details,
 * licence, user count and status; adding one also creates its first Admin. Delete and wipe are the API's
 * SuperAdmin-only routes (Phase 0.6) and ask for the pharmacy's name to be typed, as the design's level C does.
 */

interface Pharmacy {
    id: number;
    name: string;
    email: string;
    phone: string;
    address: string;
    licenseNumber: string;
    status: "Active" | "Inactive";
    createdAt: string;
    userCount?: number;
}

const apiError = (e: unknown, fallback: string): string => {
    const m = (e as { response?: { data?: { message?: string | string[] } } })?.response?.data?.message;
    return Array.isArray(m) ? m.join(", ") : m || fallback;
};

// ─── Pharmacy form ─────────────────────────────────────────────────────────

interface FormState {
    name: string; email: string; phone: string; address: string;
    licenseNumber: string; status: string;
    adminName: string; adminUsername: string; adminEmail: string; adminPassword: string;
}

const EMPTY_FORM: FormState = {
    name: "", email: "", phone: "", address: "", licenseNumber: "", status: "Active",
    adminName: "", adminUsername: "", adminEmail: "", adminPassword: "",
};

function PharmacyForm({
    pharmacy, onClose, onSaved,
}: { pharmacy?: Pharmacy | null; onClose: () => void; onSaved: (name: string) => void }) {
    const isEdit = !!pharmacy;
    const [form, setForm] = useState<FormState>(
        pharmacy
            ? { name: pharmacy.name, email: pharmacy.email || "", phone: pharmacy.phone || "", address: pharmacy.address || "", licenseNumber: pharmacy.licenseNumber || "", status: pharmacy.status, adminName: "", adminUsername: "", adminEmail: "", adminPassword: "" }
            : EMPTY_FORM
    );
    const [saving, setSaving] = useState(false);
    const [err, setErr] = useState("");

    const set = (k: keyof FormState) => (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => setForm(f => ({ ...f, [k]: e.target.value }));
    const ready = form.name.trim() !== "" && (isEdit || (form.adminName.trim() !== "" && form.adminUsername.trim() !== "" && form.adminPassword !== ""));

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        if (!ready) return;
        setErr("");
        setSaving(true);
        try {
            if (isEdit) {
                await PharmaciesApi.update(pharmacy!.id, {
                    name: form.name, email: form.email, phone: form.phone,
                    address: form.address, licenseNumber: form.licenseNumber, status: form.status,
                });
            } else {
                await PharmaciesApi.create({
                    name: form.name, email: form.email, phone: form.phone,
                    address: form.address, licenseNumber: form.licenseNumber, status: form.status,
                    adminName: form.adminName, adminUsername: form.adminUsername,
                    adminEmail: form.adminEmail || form.email, adminPassword: form.adminPassword,
                });
            }
            onSaved(form.name);
            onClose();
        } catch (e) {
            setErr(apiError(e, "Couldn't save. Try again."));
        } finally { setSaving(false); }
    };

    return (
        <Dialog open onOpenChange={(open) => { if (!open) onClose(); }}>
            <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-lg">
                <form onSubmit={handleSubmit} className="space-y-5">
                    <DialogHeader>
                        <DialogTitle>{isEdit ? `Edit ${pharmacy!.name}` : "Add pharmacy"}</DialogTitle>
                        <DialogDescription>{isEdit ? "The pharmacy's details. Its users are managed from inside the pharmacy." : "A new tenant, and the Admin account that signs in to it first."}</DialogDescription>
                    </DialogHeader>
                    {err && <Alert variant="destructive"><AlertDescription>{err}</AlertDescription></Alert>}

                    <FieldSet>
                        <FieldLegend>Pharmacy</FieldLegend>
                        <Field><FieldLabel htmlFor="ph-name">Name</FieldLabel><Input id="ph-name" value={form.name} onChange={set("name")} placeholder="e.g. Nairobi Central Pharmacy" autoFocus /></Field>
                        <div className="grid gap-3">
                            <Field><FieldLabel htmlFor="ph-email">Email</FieldLabel><Input id="ph-email" type="email" value={form.email} onChange={set("email")} placeholder="pharmacy@email.com" /></Field>
                            <Field><FieldLabel htmlFor="ph-phone">Phone</FieldLabel><Input id="ph-phone" value={form.phone} onChange={set("phone")} placeholder="+254 700 000 000" /></Field>
                        </div>
                        <Field><FieldLabel htmlFor="ph-address">Address</FieldLabel><Input id="ph-address" value={form.address} onChange={set("address")} placeholder="Street, town" /></Field>
                        <div className="grid gap-3">
                            <Field><FieldLabel htmlFor="ph-licence">Licence number</FieldLabel><Input id="ph-licence" value={form.licenseNumber} onChange={set("licenseNumber")} placeholder="PPB-2024-00001" /></Field>
                            <Field>
                                <FieldLabel htmlFor="ph-status">Status</FieldLabel>
                                <NativeSelect id="ph-status" value={form.status} onChange={set("status")} className="w-full">
                                    <NativeSelectOption value="Active">Active</NativeSelectOption>
                                    <NativeSelectOption value="Inactive">Inactive</NativeSelectOption>
                                </NativeSelect>
                            </Field>
                        </div>
                    </FieldSet>

                    {!isEdit && (
                        <FieldSet>
                            <FieldLegend>Admin account</FieldLegend>
                            <Field><FieldLabel htmlFor="ad-name">Full name</FieldLabel><Input id="ad-name" value={form.adminName} onChange={set("adminName")} placeholder="e.g. Jane Wambua" /></Field>
                            <div className="grid gap-3">
                                <Field><FieldLabel htmlFor="ad-user">Username</FieldLabel><Input id="ad-user" autoComplete="off" value={form.adminUsername} onChange={set("adminUsername")} placeholder="janewambua" /></Field>
                                <Field><FieldLabel htmlFor="ad-pass">Password</FieldLabel><Input id="ad-pass" type="password" autoComplete="new-password" value={form.adminPassword} onChange={set("adminPassword")} /></Field>
                            </div>
                            <Field>
                                <FieldLabel htmlFor="ad-email">Email</FieldLabel>
                                <Input id="ad-email" type="email" value={form.adminEmail} onChange={set("adminEmail")} />
                                <FieldDescription>Left empty, the pharmacy&apos;s email is used.</FieldDescription>
                            </Field>
                        </FieldSet>
                    )}

                    <DialogFooter>
                        <Button type="button" variant="outline" onClick={onClose}>Cancel</Button>
                        <Button type="submit" disabled={!ready || saving}>{saving ? "Saving…" : isEdit ? "Save changes" : "Add pharmacy"}</Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}

// ─── Page ──────────────────────────────────────────────────────────────────

/** Every pharmacy with its number of users. */
async function fetchPharmacies(): Promise<Pharmacy[]> {
    const data: Pharmacy[] = await PharmaciesApi.getAll();
    return Promise.all(
        data.map(async (p) => {
            try {
                const stats = await PharmaciesApi.getStats(p.id);
                return { ...p, userCount: stats.userCount };
            } catch { return { ...p, userCount: 0 }; }
        })
    );
}

export default function PharmaciesPage() {
    const router = useRouter();
    const [pharmacies, setPharmacies] = useState<Pharmacy[] | null>(null);
    const [failed, setFailed] = useState(false); // R12 (card 037): a failed load says so, with Try again
    const [modal, setModal] = useState<"create" | "edit" | "delete" | "clear-seed-data" | null>(null);
    const [selected, setSelected] = useState<Pharmacy | null>(null);

    useEffect(() => {
        // Guard: only SuperAdmin can access this page (the API refuses everyone else too, Phase 0.6)
        if (typeof window !== "undefined") {
            const userStr = localStorage.getItem("user");
            const user = userStr ? JSON.parse(userStr) : null;
            if (!user || user.role !== "SuperAdmin") router.push("/login");
        }
    }, [router]);

    // State is set only once the request answers, so the effect below never sets it synchronously
    const load = useCallback(() =>
        fetchPharmacies()
            .then((p) => (setPharmacies(p), setFailed(false)))
            .catch((e) => {
                setPharmacies([]);
                setFailed(true);
                toast.add({ type: "error", title: "Couldn't load pharmacies", description: apiError(e, "Try again.") });
            }), []);

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

    const close = () => { setModal(null); setSelected(null); };

    const cols: Col<Pharmacy>[] = [
        { key: "name", header: "Pharmacy", cell: (p) => <div><p className="font-medium">{p.name}</p><p className="text-xs text-muted-foreground">ID {p.id}</p></div> },
        { key: "contact", header: "Contact", cell: (p) => <div className="space-y-0.5 text-xs text-muted-foreground">{[p.email, p.phone, p.address].filter(Boolean).map((x) => <p key={x}>{x}</p>)}</div> },
        { key: "licence", header: "Licence", cell: (p) => p.licenseNumber || <span className="text-muted-foreground">—</span> },
        { key: "users", header: "Users", numeric: true, cell: (p) => p.userCount ?? 0, total: (shown) => shown.reduce((n, p) => n + (p.userCount ?? 0), 0) },
        { key: "status", header: "Status", cell: (p) => <Tag tone={p.status === "Active" ? "ok" : "neutral"}>{p.status}</Tag> },
        {
            key: "actions", header: "", cell: (p) => (
                <RowActions label={`Actions for ${p.name}`} actions={[
                    { label: "Edit", icon: PencilIcon, onSelect: () => { setSelected(p); setModal("edit"); } },
                    { label: "Clear data…", icon: DatabaseIcon, destructive: true, onSelect: () => { setSelected(p); setModal("clear-seed-data"); } },
                    { label: "Delete…", icon: Trash2Icon, destructive: true, onSelect: () => { setSelected(p); setModal("delete"); } },
                ]} />
            ),
        },
    ];

    return (
        <div className="space-y-6">
            <MedoraPageHeader
                title="Pharmacies"
                description="Every pharmacy using Medora. Adding one also creates its first Admin."
                meta={pharmacies ? [`${pharmacies.length} pharmac${pharmacies.length === 1 ? "y" : "ies"}`] : []}
                metaLoading={!pharmacies}
                primary={{ label: "Add pharmacy", icon: PlusIcon, onSelect: () => { setSelected(null); setModal("create"); } }}
            />

            {failed ? (
                <PanelError framed what="pharmacies" onRetry={() => void load()} />
            ) : pharmacies === null ? (
                <Loading what="pharmacies" columns={6} rows={6} toolbar={1} numeric={[3]} />
            ) : (
                <ListTable
                    rows={pharmacies}
                    cols={cols}
                    rowKey={(p) => String(p.id)}
                    search={{ placeholder: "Search name, email or phone", text: (p) => [p.name, p.email, p.phone, p.licenseNumber].join(" ") }}
                    filters={[{ label: "Status", all: "All statuses", value: (p) => p.status }]}
                    empty={pharmacies.length ? "No pharmacy matches." : "No pharmacies yet. Add the first one."}
                />
            )}

            {(modal === "create" || modal === "edit") && (
                <PharmacyForm
                    pharmacy={modal === "edit" ? selected : null}
                    onClose={close}
                    onSaved={(name) => { toast.add({ title: modal === "edit" ? `Saved ${name}` : `Added ${name}` }); load(); }}
                />
            )}

            {selected && (
                <ConfirmDialog
                    open={modal === "delete"}
                    onOpenChange={(open) => { if (!open) close(); }}
                    level="C"
                    reasonRequired={false}
                    confirmText={selected.name}
                    title={`Delete ${selected.name}?`}
                    consequences={[
                        `${selected.name} and all its data are deleted: users, products, stock, sales, customers and records.`,
                        "This can't be undone.",
                    ]}
                    actionLabel="Delete pharmacy"
                    busyLabel="Deleting…"
                    onConfirm={async () => {
                        try {
                            await PharmaciesApi.delete(selected.id);
                        } catch (e) {
                            throw new Error(apiError(e, "Couldn't delete the pharmacy."));
                        }
                        toast.add({ title: `Deleted ${selected.name}` });
                        close();
                        load();
                    }}
                />
            )}

            {selected && (
                <ConfirmDialog
                    open={modal === "clear-seed-data"}
                    onOpenChange={(open) => { if (!open) close(); }}
                    level="C"
                    reasonRequired={false}
                    confirmText={selected.name}
                    title={`Clear ${selected.name}'s data?`}
                    consequences={[
                        "Sales, products, stock, shifts, customers, the books and every user except its Admin are deleted, leaving a clean pharmacy with one new main branch.",
                        "Its Admin, its roles and the audit history are kept.",
                        "This can't be undone.",
                    ]}
                    actionLabel="Clear data"
                    busyLabel="Clearing…"
                    onConfirm={async () => {
                        try {
                            await PharmaciesApi.clearSeedData(selected.id);
                        } catch (e) {
                            throw new Error(apiError(e, "Couldn't clear the data."));
                        }
                        toast.add({ title: `Cleared ${selected.name}'s data` });
                        close();
                        load();
                    }}
                />
            )}
        </div>
    );
}
