import LogAbsensiController from "@/actions/App/Http/Controllers/LogAbsensi/IndexController";
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, usePage } from "@inertiajs/react";
import {
    useMemo,
    useCallback,
    ReactNode,
    useEffect,
    useState,
    useRef,
} from "react";
import {
    Badge,
    Button,
    Col,
    Container,
    Dropdown,
    Form,
    Image,
    Row,
} from "react-bootstrap";
import { MdAdd, MdMoreHoriz } from "react-icons/md";
import { PiCaretDown, PiCaretRight } from "react-icons/pi";
import { CellContext } from "@tanstack/react-table";
import GoogleMapEmbed from "@/components/google-map-embed";
import { SharedData } from "@/types";
import { toast } from "react-toastify";
import ListView from "@/components/listview";
import PageHeader from "@/components/page-header";
import { LogAbsensi, LogAbsensiProps } from "@/types/log-absensi";
import { dateTimeFormatter } from "@/utils/date-formatter";
import AbsenMapModal from "@/components/absen-modal";
import axios from "axios";

export default function LogAbsensiPage({ title, resource }: LogAbsensiProps) {
    const { auth, flash } = usePage<SharedData>().props;
    const [params, setParams] = useQueryParams();
    const [showModal, setShowModal] = useState(false);

    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 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({
        // Jika ada di URL gunakan itu, jika tidak gunakan default 1 bulan ini
        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 handleAbsen = (lat: number, lng: number) => {
        router.post(
            route("log-absensi.store"),
            {
                latitude: lat,
                longitude: lng,
            },
            {
                preserveScroll: true,
                onSuccess: () => {
                    setShowModal(false);
                    router.visit(window.location.pathname, {
                        only: ["resource"],
                        preserveState: false,
                    });
                },
                onError: (errors) => {
                    if (errors.absensi) {
                        toast.error(errors.absensi);
                    }
                },
            },
        );
    };

    // 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<LogAbsensi, 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: "user_nip",
                header: "NIP",
                cell: (info: any) => (
                    <div className="text-start">{info.getValue()}</div>
                ),
            },
            {
                accessorKey: "user_name",
                header: "Nama",
                cell: (info: any) => (
                    <div className="text-start small fw-bold">
                        {info.getValue()}
                    </div>
                ),
            },
            {
                accessorKey: "skpd_name",
                header: "SKPD",
                cell: (info: any) => (
                    <div className="text-start">{info.getValue()}</div>
                ),
            },
            {
                accessorKey: "tgl",
                header: "Tanggal",
                cell: (info: any) => (
                    <div className="text-start small">
                        {/* Menggunakan dateFormatter karena data tgl sekarang hanya Y-m-d */}
                        {info.getValue()}
                    </div>
                ),
            },
            {
                accessorKey: "jam_masuk",
                header: "Absen Masuk",
                cell: (info: any) => {
                    const status = info.row.original.status_masuk;
                    const value = info.getValue();

                    let variant = "secondary-subtle";
                    let textClass = "text-secondary-emphasis";

                    if (status === "Tepat Waktu") {
                        variant = "success-subtle";
                        textClass = "text-success-emphasis";
                    } else if (status === "Terlambat") {
                        variant = "danger-subtle";
                        textClass = "text-danger-emphasis";
                    } else if (status === "Pulang Cepat") {
                        variant = "warning-subtle";
                        textClass = "text-warning-emphasis";
                    }

                    // Return JSX dengan pembungkus (Fragment atau Div)
                    return (
                        <div className="d-flex gap-1">
                            <Badge
                                bg={value !== "-" ? "info-subtle" : "light"}
                                className="text-info-emphasis"
                            >
                                {value}
                            </Badge>

                            {status && (
                                <Badge bg={variant} className={textClass}>
                                    {status}
                                </Badge>
                            )}
                        </div>
                    );
                },
            },
            {
                accessorKey: "jam_pulang",
                header: "Absen Pulang",
                cell: (info: any) => {
                    const status = info.row.original.status_pulang;
                    const value = info.getValue();

                    let variant = "secondary-subtle";
                    let textClass = "text-secondary-emphasis";

                    if (status === "Tepat Waktu") {
                        variant = "success-subtle";
                        textClass = "text-success-emphasis";
                    } else if (status === "Terlambat") {
                        variant = "danger-subtle";
                        textClass = "text-danger-emphasis";
                    } else if (status === "Pulang Cepat") {
                        variant = "warning-subtle";
                        textClass = "text-warning-emphasis";
                    }

                    // Return JSX dengan pembungkus (Fragment atau Div)
                    return (
                        <div className="d-flex gap-1">
                            <Badge
                                bg={value !== "-" ? "info-subtle" : "light"}
                                className="text-info-emphasis"
                            >
                                {value}
                            </Badge>

                            {status && (
                                <Badge bg={variant} className={textClass}>
                                    {status}
                                </Badge>
                            )}
                        </div>
                    );
                },
            },
            {
                accessorKey: "lokasi_name",
                header: "Lokasi",
                cell: (info: any) => (
                    <div className="text-center p-1 px-2 rounded border border-light text-light-emphasis small">
                        {info.getValue()}
                    </div>
                ),
            },
        ],
        [resource.data],
    );

    // Data table setup - dengan key yang reactive untuk memaksa re-render
    const tableKey = useMemo(() => {
        return `${resource.meta.total}-${resource.meta.current_page}-${params.start_date}-${params.end_date}-${params.search || ""}-${params.sort || ""}-${params.order || ""}`;
    }, [
        resource.meta.total,
        resource.meta.current_page,
        params.search,
        params.start_date,
        params.end_date,
        params.sort,
        params.order,
    ]);

    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,
    });

    const canAbsen =
        auth.user?.permissions?.includes("log-absen.create") || false;
    const isPegawai = auth.user?.role === "pegawai";
    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 Absensi */}
                    <div className=" w-md-auto">
                        {isPegawai && canAbsen && (
                            <Button
                                variant="success"
                                className="btn-icon-label w-100"
                                onClick={() => setShowModal(true)}
                            >
                                <MdAdd />
                                <span>Absensi</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>
            <AbsenMapModal
                open={showModal}
                onClose={() => setShowModal(false)}
                onAbsen={handleAbsen}
                officeLocation={
                    auth.user?.lokasi
                        ? {
                              lat: parseFloat(auth.user.lokasi.latitude),
                              lng: parseFloat(auth.user.lokasi.longitude),
                              name: auth.user.lokasi.name,
                          }
                        : undefined
                }
            />
        </AppLayout>
    );
}
