import React, { useEffect, useMemo, useState } from "react";
import { Formik } from "formik";
import * as Yup from "yup";
import type { Crew, CrewListParams } from "../api";
import { createCrew, deleteCrew, exportCrews, updateCrew } from "../api";
import { useAppDispatch, useAppSelector } from "../hooks";
import { loadCrews } from "../store";
import { Button, Modal, Pagination, Select, TextArea, TextInput, useNinjaSfx, useToast } from "../ui";

type FormValues = {
    name: string;
    role: string;
    contact: string;
    description: string;
    note: string;
    sort_order: string;
    is_active: boolean;
};

const schema = Yup.object({
    name: Yup.string().required("Nama wajib diisi.").max(255),
    role: Yup.string().max(255),
    contact: Yup.string().max(255),
    description: Yup.string(),
    note: Yup.string(),
    sort_order: Yup.number()
        .transform((v, o) => (o === "" || o === null ? undefined : v))
        .min(0)
        .max(100000)
        .nullable(),
    is_active: Yup.boolean(),
});

function toFormValues(item?: Crew | null): FormValues {
    return {
        name: item?.name ?? "",
        role: item?.role ?? "",
        contact: item?.contact ?? "",
        description: item?.description ?? "",
        note: item?.note ?? "",
        sort_order: item?.sort_order === null || item?.sort_order === undefined ? "" : String(item.sort_order),
        is_active: item?.is_active ?? true,
    };
}

function buildPayload(values: FormValues): Partial<Crew> {
    return {
        name: values.name.trim(),
        role: values.role.trim() || null,
        contact: values.contact.trim() || null,
        description: values.description.trim() || null,
        note: values.note.trim() || null,
        sort_order: values.sort_order.trim() === "" ? null : Number(values.sort_order),
        is_active: values.is_active,
    };
}

export function AdminCrewsPage() {
    const dispatch = useAppDispatch();
    const { toast } = useToast();
    const sfx = useNinjaSfx();
    const state = useAppSelector((s) => s.crews);

    const [q, setQ] = useState("");
    const [active, setActive] = useState<"" | "1" | "0">("");
    const [role, setRole] = useState("");
    const [perPage, setPerPage] = useState(25);
    const [page, setPage] = useState(1);
    const [sort, setSort] = useState<string>("");

    const [editing, setEditing] = useState<Crew | null>(null);
    const [openEditor, setOpenEditor] = useState(false);
    const [confirmDelete, setConfirmDelete] = useState<Crew | null>(null);

    const listParams: CrewListParams = useMemo(
        () => ({
            q: q.trim() || undefined,
            active: active || undefined,
            role: role.trim() || undefined,
            per_page: perPage,
            page,
            sort: sort || undefined,
        }),
        [q, active, role, perPage, page, sort],
    );

    useEffect(() => {
        const t = window.setTimeout(() => {
            dispatch(loadCrews(listParams));
        }, 300);
        return () => window.clearTimeout(t);
    }, [dispatch, listParams]);

    const meta = state.meta || { page: 1, per_page: perPage, total: 0, last_page: 1 };

    return (
        <div className="ninja-card rounded-2xl border border-white/10 bg-white/[0.03] p-6 shadow-[0_20px_80px_-40px_rgba(0,0,0,0.9)] backdrop-blur">
            <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
                <div>
                    <div className="text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                        Komunitas
                    </div>
                    <div className="mt-1 text-2xl font-semibold tracking-tight text-white font-ninja">
                        <span className="text-[#FFD700]">Crew</span> Manager
                    </div>
                    <div className="mt-1 text-sm text-gray-300/80">
                        CRUD + filter/sort/pagination + export
                    </div>
                </div>
                <div className="flex flex-wrap items-center gap-2">
                    <Button type="button" tip="Tambah data" onClick={() => { setEditing(null); setOpenEditor(true); }}>
                        Tambah
                    </Button>
                    <Button
                        type="button"
                        variant="secondary"
                        tip="Export CSV"
                        onClick={() => exportCrews("csv", listParams)}
                    >
                        Export CSV
                    </Button>
                    <Button
                        type="button"
                        variant="secondary"
                        tip="Export Excel"
                        onClick={() => exportCrews("excel", listParams)}
                    >
                        Export Excel
                    </Button>
                </div>
            </div>

            <div className="mt-6 grid grid-cols-1 gap-3 lg:grid-cols-12">
                <TextInput
                    className="lg:col-span-5"
                    label="Cari"
                    value={q}
                    onChange={(e) => { setPage(1); setQ(e.target.value); }}
                    placeholder="Nama..."
                />
                <Select
                    className="lg:col-span-3"
                    label="Status"
                    value={active}
                    onChange={(e) => { setPage(1); setActive(e.target.value as any); }}
                >
                    <option value="">Semua</option>
                    <option value="1">Aktif</option>
                    <option value="0">Nonaktif</option>
                </Select>
                <TextInput
                    className="lg:col-span-4"
                    label="Role"
                    value={role}
                    onChange={(e) => { setPage(1); setRole(e.target.value); }}
                    placeholder="Contoh: Leader"
                />
                <Select
                    className="lg:col-span-3"
                    label="Per Halaman"
                    value={String(perPage)}
                    onChange={(e) => { setPage(1); setPerPage(Number(e.target.value)); }}
                >
                    <option value="10">10</option>
                    <option value="25">25</option>
                    <option value="50">50</option>
                    <option value="100">100</option>
                </Select>
                <Select
                    className="lg:col-span-9"
                    label="Sorting"
                    value={sort}
                    onChange={(e) => { setPage(1); setSort(e.target.value); }}
                >
                    <option value="">Default (sort_order asc, id desc)</option>
                    <option value="name:asc">Name ↑</option>
                    <option value="name:desc">Name ↓</option>
                    <option value="created_at:desc">Created ↓</option>
                    <option value="created_at:asc">Created ↑</option>
                    <option value="is_active:desc">Aktif dulu</option>
                    <option value="is_active:asc">Nonaktif dulu</option>
                </Select>
            </div>

            <div className="mt-6 overflow-x-auto rounded-2xl border border-white/10">
                <table className="min-w-full divide-y divide-white/10">
                    <thead>
                        <tr className="bg-white/[0.02] text-left text-xs font-semibold uppercase tracking-[0.18em] text-gray-300">
                            <th className="py-3.5 pl-4 pr-4">Nama</th>
                            <th className="py-3.5 pr-4">Role</th>
                            <th className="py-3.5 pr-4">Kontak</th>
                            <th className="py-3.5 pr-4">Status</th>
                            <th className="py-3.5 pr-4 text-right">Action</th>
                        </tr>
                    </thead>
                    <tbody className="divide-y divide-white/10">
                        {state.loading ? (
                            <tr>
                                <td colSpan={5} className="px-4 py-8 text-sm text-gray-300/80">
                                    Memuat...
                                </td>
                            </tr>
                        ) : state.items.length === 0 ? (
                            <tr>
                                <td colSpan={5} className="px-4 py-8 text-sm text-gray-300/80">
                                    Tidak ada data.
                                </td>
                            </tr>
                        ) : (
                            state.items.map((item) => (
                                <tr key={item.id} className="text-sm text-gray-200 transition duration-300 hover:bg-white/[0.02]">
                                    <td className="py-3.5 pl-4 pr-4">
                                        <div className="font-semibold text-white">{item.name}</div>
                                        {item.description ? (
                                            <div className="mt-0.5 max-w-[40rem] truncate text-xs text-gray-300/70">
                                                {item.description}
                                            </div>
                                        ) : null}
                                    </td>
                                    <td className="py-3.5 pr-4 text-xs text-gray-300/80">{item.role || "-"}</td>
                                    <td className="py-3.5 pr-4 text-xs text-gray-300/80">{item.contact || "-"}</td>
                                    <td className="py-3.5 pr-4">
                                        <span
                                            className={
                                                "inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold ring-1 " +
                                                (item.is_active
                                                    ? "bg-emerald-500/15 text-emerald-200 ring-emerald-500/30"
                                                    : "bg-white/5 text-gray-200 ring-white/10")
                                            }
                                        >
                                            {item.is_active ? "Aktif" : "Nonaktif"}
                                        </span>
                                    </td>
                                    <td className="py-3.5 pr-4 text-right">
                                        <div className="inline-flex items-center gap-2">
                                            <Button
                                                type="button"
                                                variant="secondary"
                                                onClick={() => { setEditing(item); setOpenEditor(true); }}
                                            >
                                                Edit
                                            </Button>
                                            <Button
                                                type="button"
                                                variant="danger"
                                                onClick={() => setConfirmDelete(item)}
                                            >
                                                Hapus
                                            </Button>
                                        </div>
                                    </td>
                                </tr>
                            ))
                        )}
                    </tbody>
                </table>
            </div>

            <div className="mt-6">
                <Pagination page={meta.page} lastPage={meta.last_page} onPage={setPage} />
            </div>

            <Modal
                open={openEditor}
                title={editing ? `Edit Crew #${editing.id}` : "Tambah Crew"}
                onClose={() => setOpenEditor(false)}
                footer={null}
            >
                <Formik
                    initialValues={toFormValues(editing)}
                    validationSchema={schema}
                    enableReinitialize
                    onSubmit={async (values, helpers) => {
                        helpers.setSubmitting(true);
                        try {
                            sfx.play("save");
                            if (editing) {
                                await updateCrew(editing.id, buildPayload(values));
                                toast("success", "Crew diupdate.");
                            } else {
                                await createCrew(buildPayload(values));
                                toast("success", "Crew dibuat.");
                            }
                            setOpenEditor(false);
                            await dispatch(loadCrews({ ...listParams, page: 1 }));
                            setPage(1);
                        } catch (e: any) {
                            const msg =
                                e?.response?.data?.message ||
                                (e?.response?.status === 422 ? "Validasi gagal." : "Gagal menyimpan.");
                            toast("error", msg);
                        } finally {
                            helpers.setSubmitting(false);
                        }
                    }}
                >
                    {({ handleSubmit, values, errors, touched, isSubmitting, setFieldValue }) => (
                        <form onSubmit={handleSubmit} className="grid grid-cols-1 gap-4 lg:grid-cols-2">
                            <TextInput
                                label="Nama"
                                value={values.name}
                                onChange={(e) => setFieldValue("name", e.target.value)}
                                error={touched.name ? (errors.name as any) : null}
                                placeholder="Nama crew"
                                className="lg:col-span-2"
                            />
                            <TextInput
                                label="Role"
                                value={values.role}
                                onChange={(e) => setFieldValue("role", e.target.value)}
                                error={touched.role ? (errors.role as any) : null}
                                placeholder="Role / jabatan"
                            />
                            <TextInput
                                label="Kontak"
                                value={values.contact}
                                onChange={(e) => setFieldValue("contact", e.target.value)}
                                error={touched.contact ? (errors.contact as any) : null}
                                placeholder="WA / Discord / dsb"
                            />
                            <TextInput
                                label="Sort Order"
                                value={values.sort_order}
                                onChange={(e) => setFieldValue("sort_order", e.target.value)}
                                error={touched.sort_order ? (errors.sort_order as any) : null}
                                placeholder="0..100000"
                            />
                            <Select
                                label="Aktif"
                                value={values.is_active ? "1" : "0"}
                                onChange={(e) => setFieldValue("is_active", e.target.value === "1")}
                            >
                                <option value="1">Aktif</option>
                                <option value="0">Nonaktif</option>
                            </Select>
                            <TextArea
                                label="Deskripsi"
                                value={values.description}
                                onChange={(e) => setFieldValue("description", e.target.value)}
                                error={touched.description ? (errors.description as any) : null}
                                rows={4}
                                className="lg:col-span-2"
                            />
                            <TextArea
                                label="Note"
                                value={values.note}
                                onChange={(e) => setFieldValue("note", e.target.value)}
                                error={touched.note ? (errors.note as any) : null}
                                rows={3}
                                className="lg:col-span-2"
                            />
                            <div className="lg:col-span-2 flex justify-end gap-2">
                                <Button
                                    type="button"
                                    variant="secondary"
                                    onClick={() => setOpenEditor(false)}
                                >
                                    Batal
                                </Button>
                                <Button type="submit" disabled={isSubmitting}>
                                    Simpan
                                </Button>
                            </div>
                        </form>
                    )}
                </Formik>
            </Modal>

            <Modal
                open={!!confirmDelete}
                title={confirmDelete ? `Hapus Crew #${confirmDelete.id}?` : "Hapus"}
                onClose={() => setConfirmDelete(null)}
                widthClassName="max-w-xl"
                footer={
                    <>
                        <Button
                            type="button"
                            variant="secondary"
                            onClick={() => setConfirmDelete(null)}
                        >
                            Batal
                        </Button>
                        <Button
                            type="button"
                            variant="danger"
                            onClick={async () => {
                                if (!confirmDelete) return;
                                try {
                                    sfx.play("delete");
                                    await deleteCrew(confirmDelete.id);
                                    toast("success", "Crew dihapus.");
                                    setConfirmDelete(null);
                                    await dispatch(loadCrews(listParams));
                                } catch (e: any) {
                                    toast("error", e?.response?.data?.message || "Gagal menghapus.");
                                }
                            }}
                        >
                            Ya, hapus
                        </Button>
                    </>
                }
            >
                <div className="text-sm text-gray-200">
                    Tindakan ini tidak bisa dibatalkan.
                </div>
            </Modal>
        </div>
    );
}
