import AppPagination from "@/components/app-pagination";
import DataTable from "@/components/data-table";
import EmptyData from "@/components/empty-data";
import { useQueryParams } from "@/hooks/use-query-params";
import { useDataTable } from "@/hooks/use-data-table";
import { useSearch } from "@/hooks/use-search";
import { useExpanding } from "@/hooks/use-expanding";
import AppLayout, { MySwalTheme } from "@/layouts/app-layout";
import { Head, router, useForm, usePage } from "@inertiajs/react";
import { useMemo, useCallback, ReactNode, useEffect, useState } from "react";
import {
    Badge,
    Button,
    Col,
    Container,
    Dropdown,
    Form,
    Image,
    Modal,
    Row,
} from "react-bootstrap";
import { MdAdd, MdFileOpen, MdLock, MdMoreHoriz } from "react-icons/md";
import { PiNavigationArrowFill } from "react-icons/pi";
import { CellContext } from "@tanstack/react-table";
import { SelectOption, SelectOptionString, SharedData } from "@/types";
import { toast } from "react-toastify";
import PageHeader from "@/components/page-header";
import Select from "react-select";
import { Izin, IzinForm, IzinProps } from "@/types/izin";
import IzinController from "@/actions/App/Http/Controllers/Izin/IndexController";
import useReactSelectTheme from "@/hooks/use-react-select";

export default function IzinPage({ title, resource, refTipeIzin }: IzinProps) {
    const theme = useReactSelectTheme();
    const { auth, flash } = usePage<SharedData>().props;
    const [params, setParams] = useQueryParams();
    const [showModal, setShowModal] = useState(false);
    const [selected, setSelected] = useState<any>(null);

    const { data, setData, post, put, processing, errors, reset } =
        useForm<IzinForm>({
            users_id: null,
            keterangan: "",
            tipe: "",
            jenis: "",
            tgl_mulai: "",
            tgl_selesai: "",
            file: "",
        });

    useEffect(() => {
        if (flash?.success) {
            toast.success(flash.success);
        }
        if (flash?.error) {
            toast.error(flash.error);
        }
    }, [flash]);

    // Expanding functionality
    const {
        expanded,
        toggleExpanded,
        expandAll,
        collapseAll,
        isExpanded,
        expandedCount,
    } = useExpanding({
        multipleExpansion: true,
    });

    // Search functionality
    const { searchValue, handleSearch } = useSearch({
        initialValue: params.search || "",
        onSearch: useCallback(
            (value: string) => {
                // Jika value kosong, pass undefined untuk menghapus parameter search dari URL
                setParams({ search: value.trim() || undefined });
            },
            [setParams],
        ),
        debounceMs: 500,
    });

    // Sort handler
    const handleSort = useCallback(
        (columnId: string) => {
            const isCurrentSort = params.sort === columnId;
            const isDesc = isCurrentSort && params.order === "desc";
            const newOrder = isDesc ? "asc" : "desc";

            setParams({
                sort: columnId,
                order: newOrder,
            });
        },
        [params.sort, params.order, setParams],
    );

    // Pagination handlers
    const handlePageChange = useCallback(
        (page: number) => {
            setParams({ page });
        },
        [setParams],
    );

    const handlePerPageChange = useCallback(
        (perPage: number) => {
            setParams({ per_page: perPage });
        },
        [setParams],
    );

    const [jenisOptions, setJenisOptions] = useState<any[]>([]);

    // Handler saat Tipe Izin berubah
    const handleTipeChange = (selectedOption: any) => {
        const tipeName = selectedOption ? selectedOption.value : "";
        setData("tipe", tipeName);
        setData("jenis", ""); // Reset jenis saat tipe berubah

        // Cari data tipe yang dipilih untuk mengambil anak-anaknya (jenis)
        const selectedTipeData = refTipeIzin.find(
            (t: any) => t.name === tipeName,
        );
        if (selectedTipeData && selectedTipeData.jenis_izin) {
            const options = selectedTipeData.jenis_izin.map((j: any) => ({
                value: j.name,
                label: j.name,
            }));
            setJenisOptions(options);
        } else {
            setJenisOptions([]);
        }
    };

    // Sinkronisasi jenisOptions saat Edit Modal dibuka
    useEffect(() => {
        if (selected && data.tipe) {
            const selectedTipeData = refTipeIzin.find(
                (t: any) => t.name === data.tipe,
            );
            if (selectedTipeData?.jenis_izin) {
                setJenisOptions(
                    selectedTipeData.jenis_izin.map((j: any) => ({
                        value: j.name,
                        label: j.name,
                    })),
                );
            }
        }
    }, [selected]);
    const now = new Date();

    const toLocalISO = (date: Date) => {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        const day = String(date.getDate()).padStart(2, "0");
        return `${year}-${month}-${day}`;
    };

    const firstDayOfMonth = toLocalISO(
        new Date(now.getFullYear(), now.getMonth(), 1),
    );

    const lastDayOfMonth = toLocalISO(
        new Date(now.getFullYear(), now.getMonth() + 1, 0),
    );

    const [dateFilter, setDateFilter] = useState({
        start: params.start_date || firstDayOfMonth,
        end: params.end_date || lastDayOfMonth,
    });

    const handleResetFilter = () => {
        setDateFilter({
            start: firstDayOfMonth,
            end: lastDayOfMonth,
        });
        setParams({
            ...params,
            search: "",
            start_date: firstDayOfMonth,
            end_date: lastDayOfMonth,
            page: 1,
        });
    };

    // Handler untuk tombol filter
    const handleApplyFilter = () => {
        setParams({
            ...params,
            start_date: dateFilter.start,
            end_date: dateFilter.end,
            page: 1,
        });
    };

    const handleCreateOpen = () => {
        setSelected(null);
        setData({
            users_id: null,
            keterangan: "",
            tipe: "",
            jenis: "",
            tgl_mulai: "",
            tgl_selesai: "",
            file: "",
        });
        setJenisOptions([]); // Reset opsi jenis
        reset();
        setShowModal(true);
    };

    const handleEditOpen = (izin: any) => {
        if (izin.status !== "Menunggu") {
            toast.error("Data yang sudah diproses tidak dapat diubah.");
            return;
        }
        setSelected(izin);
        setData({
            users_id: Number(izin.users_id),
            tgl_mulai: izin.tgl_mulai ?? "",
            tgl_selesai: izin.tgl_selesai ?? "",
            tipe: izin.tipe ?? "",
            jenis: izin.jenis ?? "",
            keterangan: izin.keterangan ?? "",
            file: izin.file ?? "",
        });
        setShowModal(true);
    };

    const handleSubmit = () => {
        if (selected) {
            const payload = {
                ...data,
                _method: "put",
                file: data.file instanceof File ? data.file : null,
            };

            router.post(`/izin/${selected.id}`, payload, {
                forceFormData: true,
                preserveScroll: true,
                onSuccess: () => {
                    setShowModal(false);
                    reset();
                    MySwalTheme.fire({
                        icon: "success",
                        title: "Berhasil",
                        text: "Data Izin berhasil diperbarui",
                        timer: 1500,
                        showConfirmButton: false,
                    });
                },
                onError: (err: any) => {},
            });
        } else {
            post("/izin", {
                preserveScroll: true,
                onSuccess: () => {
                    setShowModal(false);
                    reset();
                },
            });
        }
    };
    const handleDelete = useCallback((item: Izin) => {
        MySwalTheme.fire({
            title: "Are you sure?",
            html: `Data Izin akan dihapus secara permanen.<br/><small class="text-danger">Tindakan ini tidak dapat dibatalkan.</small>`,
            icon: "question",
            confirmButtonText: "Delete",
            showCancelButton: true,
        }).then((val) => {
            if (val.isConfirmed) {
                return router.delete(`/izin/${item.id}`, {
                    preserveScroll: true,
                    onSuccess: () => {
                        MySwalTheme.fire({
                            icon: "success",
                            title: "Berhasil",
                            text: "Data Izin berhasil dihapus",
                            timer: 1500,
                            showConfirmButton: false,
                        });
                    },
                });
            }
        });
    }, []);
    const handleUpdateStatus = (id: number) => {
        MySwalTheme.fire({
            title: `Kirim`,
            text: `Apakah Anda yakin data sudah benar?`,
            icon: "info",
            showCancelButton: true,
            confirmButtonText: "Ya, Kirim",
        }).then((result) => {
            if (result.isConfirmed) {
                // POST mendukung callback onSuccess
                router.post(
                    `/izin/${id}/konfirmasi`,
                    {},
                    {
                        preserveScroll: true,
                        preserveState: false,
                        onSuccess: () => {
                            toast.success(`Izin berhasil dikirim`);
                        },
                    },
                );
            }
        });
    };

    const canIzin = auth.user?.permissions?.includes("izin.create") || false;
    const canKonfirmasi =
        auth.user?.permissions?.includes("izin.konfirmasi") || false;

    // Column definitions - memoized with resource.data dependency untuk re-render ketika data berubah
    const columns = useMemo(
        () => [
            {
                id: "rowNumber",
                header: () => <div className="text-center">No</div>,
                cell: (info: CellContext<Izin, ReactNode>) => {
                    const pageIndex = table.getState().pagination.pageIndex;
                    const pageSize = table.getState().pagination.pageSize;
                    const globalIndex =
                        pageIndex * pageSize + info.row.index + 1;
                    return <div className="text-center">{globalIndex}</div>;
                },
            },
            {
                accessorKey: "nip",
                id: "nip",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="text-start">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">NIP</div>,
            },
            {
                accessorKey: "name",
                id: "name",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="text-start small">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">Nama</div>,
            },
            {
                accessorKey: "skpd_name",
                id: "skpd_name",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="text-start small">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">SKPD</div>,
            },
            {
                accessorKey: "tgl_mulai",
                id: "tgl_mulai",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="d-flex flex-column gap-1 small text-nowrap">
                        <div className="text-muted">
                            {info.row.original.tgl_mulai}
                        </div>
                        <div className="text-primary fw-medium">
                            {info.row.original.tgl_selesai}
                        </div>
                    </div>
                ),
                header: "Rentang Tanggal",
            },
            {
                accessorKey: "tipe",
                id: "tipe",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="text-start small">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">Tipe</div>,
            },
            {
                accessorKey: "jenis",
                id: "jenis",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="text-start small">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">Jenis</div>,
            },
            {
                accessorKey: "file",
                id: "file",
                header: "File",
                cell: (info: any) => {
                    const fileName = info.getValue();
                    return fileName ? (
                        <a
                            href={`/storage/${fileName}`}
                            target="_blank"
                            className="btn btn-xs btn-outline-info btn-sm"
                        >
                            <MdFileOpen></MdFileOpen>
                        </a>
                    ) : (
                        <span className="text-muted small">-</span>
                    );
                },
            },
            {
                accessorKey: "keterangan",
                id: "keterangan",
                enableSorting: true,
                cell: (info: CellContext<Izin, ReactNode>) => (
                    <div className="text-start small">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">Keterangan</div>,
            },
            {
                accessorKey: "status",
                id: "status",
                header: "Status",
                cell: (info: CellContext<Izin, ReactNode>) => {
                    const status = info.getValue() as string;
                    let variant = "warning";
                    if (status === "Disetujui") variant = "success";

                    return <Badge bg={variant}>{status}</Badge>;
                },
            },
            {
                id: "actions",
                header: "Actions",
                size: 150,
                cell: (info: CellContext<Izin, ReactNode>) => {
                    const row = info.row.original;
                    const isPending = row.status === "Menunggu";

                    return (
                        <div className="d-flex gap-2">
                            {/* Tombol Verifikasi (Hanya muncul jika Menunggu) */}
                            {isPending && canKonfirmasi && (
                                <>
                                    <Button
                                        size="sm"
                                        variant="outline-success"
                                        onClick={() =>
                                            handleUpdateStatus(row.id)
                                        }
                                        title="Setujui Izin"
                                    >
                                        Setujui
                                    </Button>
                                </>
                            )}

                            {/* Dropdown Edit/Delete (Hanya muncul jika Menunggu) */}
                            {isPending && canIzin ? (
                                <Dropdown drop="end" className="no-caret">
                                    <Dropdown.Toggle
                                        variant="light-subtle"
                                        size="sm"
                                    >
                                        <MdMoreHoriz />
                                    </Dropdown.Toggle>
                                    <Dropdown.Menu>
                                        <Dropdown.Item
                                            onClick={() => handleEditOpen(row)}
                                        >
                                            Edit
                                        </Dropdown.Item>
                                        <Dropdown.Item
                                            onClick={() => handleDelete(row)}
                                        >
                                            Delete
                                        </Dropdown.Item>
                                    </Dropdown.Menu>
                                </Dropdown>
                            ) : (
                                // Jika sudah disetujui/tolak, tampilkan ikon kunci atau teks
                                <Badge
                                    bg="light"
                                    text="dark"
                                    className="border"
                                >
                                    <MdLock></MdLock>
                                </Badge>
                            )}
                        </div>
                    );
                },
            },
        ],
        [handleUpdateStatus, handleEditOpen, handleDelete, canIzin],
    );

    // Data table setup - dengan key yang reactive untuk memaksa re-render
    const tableKey = useMemo(() => {
        const dataSignature = resource.data
            .map((item) => `${item.updated_at}`)
            .join("|");
        return `${resource.meta}-${params.search || ""}-${params.sort || ""}-${params.order || ""}-${dataSignature}`;
    }, [resource.meta, params, resource.data]);

    const { table } = useDataTable({
        data: resource.data,
        columns,
        pageCount: resource.meta.last_page,
        currentPage: resource.meta.current_page,
        pageSize: resource.meta.per_page,
        params,
        onSort: handleSort,
        onPageChange: handlePageChange,
        onPerPageChange: handlePerPageChange,
    });

    return (
        <AppLayout>
            <Head title={title} />

            <Container fluid className="p-0">
                <PageHeader title={title} />
                <div className="mb-4 d-flex flex-column flex-md-row align-items-start align-items-md-center justify-content-between gap-3">
                    <div className="d-flex flex-column flex-md-row align-items-stretch align-items-md-center gap-2 w-100 w-md-auto">
                        {/* Search Input */}
                        <div className="position-relative">
                            <Form.Control
                                type="search"
                                name="search"
                                value={searchValue}
                                onChange={handleSearch}
                                placeholder="Search..."
                                className="w-100"
                                style={{ minWidth: "250px" }}
                            />
                        </div>

                        {/* --- Input Filter Tanggal --- */}
                        <div className="d-flex flex-column flex-sm-row align-items-stretch align-items-sm-center gap-2 p-2">
                            <div className="d-flex align-items-center gap-2">
                                <Form.Control
                                    type="date"
                                    value={dateFilter.start}
                                    onChange={(e) =>
                                        setDateFilter({
                                            ...dateFilter,
                                            start: e.target.value,
                                        })
                                    }
                                />
                                <span className="text-muted">s/d</span>
                                <Form.Control
                                    type="date"
                                    value={dateFilter.end}
                                    onChange={(e) =>
                                        setDateFilter({
                                            ...dateFilter,
                                            end: e.target.value,
                                        })
                                    }
                                />
                            </div>
                            <div className="d-flex gap-2">
                                <Button
                                    variant="primary"
                                    className="flex-fill"
                                    onClick={handleApplyFilter}
                                >
                                    Filter
                                </Button>
                                {(params.start_date || params.end_date) && (
                                    <Button
                                        variant="outline-secondary"
                                        className="flex-fill"
                                        onClick={handleResetFilter}
                                    >
                                        Reset
                                    </Button>
                                )}
                            </div>
                        </div>
                    </div>

                    {/* Tombol Tambah */}
                    <div className=" w-md-auto">
                        {canIzin && (
                            <Button
                                variant="success"
                                className="btn-icon-label w-100"
                                onClick={() => handleCreateOpen()}
                            >
                                <MdAdd />
                                <span>Tambah</span>
                            </Button>
                        )}
                    </div>
                </div>

                <DataTable
                    key={tableKey}
                    table={table}
                    params={params}
                    onSort={handleSort}
                    defaultSortColumn="tgl"
                    isExpanded={isExpanded}
                />

                {resource.meta.total === 0 && <EmptyData />}

                <AppPagination
                    meta={resource.meta}
                    onPageChange={handlePageChange}
                    onPerPageChange={handlePerPageChange}
                />
            </Container>

            <Modal
                size="xl"
                fullscreen="md-down"
                show={showModal}
                onHide={() => setShowModal(false)}
                centered
            >
                <Modal.Header closeButton>
                    <Modal.Title>
                        {selected ? "Edit Izin" : "Tambah Izin"}
                    </Modal.Title>
                </Modal.Header>

                <Modal.Body>
                    <Form>
                        <Row>
                            {/* SELECT TIPE IZIN */}
                            <Col md={6} className="mb-3">
                                <Form.Group>
                                    <Form.Label>Tipe Izin</Form.Label>
                                    <Select
                                        options={refTipeIzin.map((t: any) => ({
                                            value: t.name,
                                            label: t.name,
                                        }))}
                                        value={{
                                            value: data.tipe,
                                            label: data.tipe || "Pilih Tipe...",
                                        }}
                                        onChange={handleTipeChange}
                                        placeholder="Pilih Tipe..."
                                        styles={theme}
                                    />
                                    {errors.tipe && (
                                        <div className="text-danger small">
                                            {errors.tipe}
                                        </div>
                                    )}
                                </Form.Group>
                            </Col>

                            {/* SELECT JENIS IZIN (Dependent) */}
                            <Col md={6} className="mb-3">
                                <Form.Group>
                                    <Form.Label>Jenis Izin</Form.Label>
                                    <Select
                                        options={jenisOptions}
                                        value={
                                            data.jenis
                                                ? {
                                                      value: data.jenis,
                                                      label: data.jenis,
                                                  }
                                                : null
                                        }
                                        onChange={(opt: any) =>
                                            setData(
                                                "jenis",
                                                opt ? opt.value : "",
                                            )
                                        }
                                        placeholder={
                                            data.tipe
                                                ? "Pilih Jenis..."
                                                : "Pilih Tipe Terlebih Dahulu"
                                        }
                                        isDisabled={!data.tipe}
                                        styles={theme}
                                    />
                                    {errors.jenis && (
                                        <div className="text-danger small">
                                            {errors.jenis}
                                        </div>
                                    )}
                                </Form.Group>
                            </Col>
                            <Col md={6} className="mt-3">
                                <Form.Group>
                                    <Form.Label>Tanggal Mulai</Form.Label>
                                    <Form.Control
                                        type="date"
                                        value={data.tgl_mulai}
                                        placeholder="Masukkan tgl_mulai"
                                        onChange={(e) =>
                                            setData("tgl_mulai", e.target.value)
                                        }
                                        isInvalid={!!errors.tgl_mulai}
                                    />
                                    <Form.Control.Feedback type="invalid">
                                        {errors.tgl_mulai}
                                    </Form.Control.Feedback>
                                </Form.Group>
                            </Col>
                            <Col md={6} className="mt-3">
                                <Form.Group>
                                    <Form.Label>Tanggal Selesai</Form.Label>
                                    <Form.Control
                                        type="date"
                                        value={data.tgl_selesai}
                                        placeholder="Masukkan tgl_selesai"
                                        onChange={(e) =>
                                            setData(
                                                "tgl_selesai",
                                                e.target.value,
                                            )
                                        }
                                        isInvalid={!!errors.tgl_selesai}
                                    />
                                    <Form.Control.Feedback type="invalid">
                                        {errors.tgl_selesai}
                                    </Form.Control.Feedback>
                                </Form.Group>
                            </Col>
                            <Col md={12} className="mt-3">
                                <Form.Group>
                                    <Form.Label>
                                        Lampiran Dokumen{" "}
                                        <small className="text-danger">
                                            (Max 2MB: PDF, JPG, PNG)
                                        </small>
                                    </Form.Label>
                                    <Form.Control
                                        type="file"
                                        onChange={(e: any) =>
                                            setData("file", e.target.files[0])
                                        }
                                        isInvalid={!!errors.file}
                                    />
                                    <Form.Control.Feedback type="invalid">
                                        {errors.file}
                                    </Form.Control.Feedback>

                                    {/* Tampilkan indikator jika file sudah ada (Saat Edit) */}
                                    {selected?.file && (
                                        <div className="mt-2 p-2 bg-light border rounded d-flex align-items-center justify-content-between">
                                            <small
                                                className="text-muted text-truncate"
                                                style={{ maxWidth: "200px" }}
                                            >
                                                File tersimpan:{" "}
                                                {selected.file.split("/").pop()}
                                            </small>
                                            <a
                                                href={`/storage/${selected.file}`}
                                                target="_blank"
                                                rel="noreferrer"
                                                className="btn btn-sm btn-link"
                                            >
                                                Pratinjau
                                            </a>
                                        </div>
                                    )}
                                </Form.Group>
                            </Col>
                            <Col md={12} className="mt-3">
                                <Form.Group>
                                    <Form.Label>Keterangan</Form.Label>
                                    <Form.Control
                                        as="textarea"
                                        rows={3}
                                        placeholder="Masukkan Keterangan lengkap"
                                        value={data.keterangan}
                                        onChange={(e) =>
                                            setData(
                                                "keterangan",
                                                e.target.value,
                                            )
                                        }
                                        isInvalid={!!errors.keterangan}
                                        style={{ resize: "none" }} // Opsional: mencegah Izin menarik/mengubah ukuran textarea
                                    />
                                    <Form.Control.Feedback type="invalid">
                                        {errors.keterangan}
                                    </Form.Control.Feedback>
                                </Form.Group>
                            </Col>
                        </Row>
                    </Form>
                </Modal.Body>

                <Modal.Footer>
                    <Button
                        variant="secondary"
                        onClick={() => setShowModal(false)}
                    >
                        Batal
                    </Button>
                    <Button
                        variant="success"
                        onClick={handleSubmit}
                        disabled={processing}
                    >
                        {processing ? "Menyimpan..." : "Simpan"}
                    </Button>
                </Modal.Footer>
            </Modal>
        </AppLayout>
    );
}
