import RefLokasiController from "@/actions/App/Http/Controllers/Master/RefLokasiController";
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, MdMoreHoriz } from "react-icons/md";
import {
    PiCaretDown,
    PiCaretRight,
    PiNavigationArrowFill,
} from "react-icons/pi";
import { CellContext } from "@tanstack/react-table";
import GoogleMapEmbed from "@/components/google-map-embed";
import { SelectOption, SharedData } from "@/types";
import { toast } from "react-toastify";
import ListView from "@/components/listview";
import PageHeader from "@/components/page-header";
import { RefLokasi, RefLokasiForm, RefLokasiProps } from "@/types/ref-lokasi";
import { dateTimeFormatter, timeFormatter } from "@/utils/date-formatter";
import { time } from "console";
import { GoogleMap, Marker, useJsApiLoader } from "@react-google-maps/api";
import Select from "react-select";
import { number } from "framer-motion";
import useReactSelectTheme from "@/hooks/use-react-select";

export default function RefLokasiPage({ title, resource }: RefLokasiProps) {
    const theme = useReactSelectTheme();
    const { flash } = usePage<SharedData>().props;
    const [params, setParams] = useQueryParams();
    const [showModal, setShowModal] = useState(false);
    const [selected, setSelected] = useState<any>(null);
    const [selectedLokasi, setSelectedLokasi] = useState<any>(null);
    const [center, setCenter] = useState({ lat: -7.8169, lng: 112.0113 });

    const { isLoaded } = useJsApiLoader({
        googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY as string,
        libraries: ["places"],
    });
    const { skpdOptions } = usePage<{
        skpdOptions: SelectOption[];
    }>().props;

    const { data, setData, post, put, processing, errors, reset } =
        useForm<RefLokasiForm>({
            skpd_id: null,
            name: "",
            latitude: "",
            longitude: "",
        });

    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 handleMapClick = (event: google.maps.MapMouseEvent) => {
        if (event.latLng) {
            const lat = event.latLng.lat();
            const lng = event.latLng.lng();
            setData("latitude", lat.toString());
            setData("longitude", lng.toString());
            setCenter({ lat, lng });
        }
    };

    const handleLokasiSaya = () => {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
                (pos) => {
                    const lat = pos.coords.latitude;
                    const lng = pos.coords.longitude;
                    setData("latitude", lat.toString());
                    setData("longitude", lng.toString());
                    setCenter({ lat, lng });
                },
                (err) => {
                    alert("Gagal ambil lokasi: " + err.message);
                },
            );
        }
    };

    const handleCreateOpen = () => {
        setSelected(null);
        setData({
            skpd_id: null,
            name: "",
            latitude: "",
            longitude: "",
        });
        setShowModal(true);
    };

    const handleEditOpen = (lokasi: any) => {
        setSelected(lokasi);
        setData({
            skpd_id: Number(lokasi.skpd_id),
            name: lokasi.name ?? "",
            latitude: lokasi.latitude ?? "",
            longitude: lokasi.longitude ?? "",
        });
        setShowModal(true);
    };
    const handleSubmit = () => {
        if (selected) {
            put(`/ref-lokasi/${selected.id}`, {
                preserveScroll: true,
                onSuccess: () => {
                    MySwalTheme.fire({
                        icon: "success",
                        title: "Berhasil",
                        text: "Data Ref Lokasi berhasil diperbarui",
                        timer: 1500,
                        showConfirmButton: false,
                    });

                    setShowModal(false);
                    reset();
                },
            });
        } else {
            post("/ref-lokasi", {
                preserveScroll: true,
                onSuccess: () => {
                    MySwalTheme.fire({
                        icon: "success",
                        title: "Berhasil",
                        text: "Data Ref Lokasi berhasil disimpan",
                        timer: 1500,
                        showConfirmButton: false,
                    });

                    setShowModal(false);
                    reset();
                },
            });
        }
    };

    const handleDelete = useCallback((item: RefLokasi) => {
        MySwalTheme.fire({
            title: "Are you sure?",
            html: `Data <b>"${item.name}"</b> 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(RefLokasiController.destroy.url(item.id), {
                    preserveScroll: true,
                    onSuccess: () => {
                        MySwalTheme.fire({
                            icon: "success",
                            title: "Berhasil",
                            text: "Data Ref Lokasi berhasil dihapus",
                            timer: 1500,
                            showConfirmButton: false,
                        });
                        router.reload({ only: ["resource"] });
                    },
                });
            }
        });
    }, []);

    // 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<RefLokasi, 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: "skpd_name",
                id: "skpd_name",
                enableSorting: true,
                cell: (info: CellContext<RefLokasi, ReactNode>) => (
                    <div className="text-start">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">Unit Kerja</div>,
            },
            {
                accessorKey: "name",
                id: "name",
                enableSorting: true,
                cell: (info: CellContext<RefLokasi, ReactNode>) => (
                    <div className="text-start small">{info.getValue()}</div>
                ),
                header: () => <div className="text-start">Nama</div>,
            },
            {
                id: "lokasi",
                header: "Lokasi",
                size: 80,
                enableSorting: false,
                cell: (info: CellContext<RefLokasi, ReactNode>) => (
                    <a
                        href={`https://www.google.com/maps?q=${info.row.original.latitude},${info.row.original.longitude}`}
                        target="_blank"
                    >
                        <Button variant="outline-primary" size="sm">
                            📍 Lokasi
                        </Button>
                    </a>
                ),
            },
            {
                id: "actions",
                header: "Actions",
                size: 80,
                enableSorting: false,
                cell: (info: CellContext<RefLokasi, ReactNode>) => (
                    <Dropdown drop="end" className="no-caret">
                        <Dropdown.Toggle
                            variant="light-subtle"
                            id="dropdown-actions"
                            size="sm"
                        >
                            <MdMoreHoriz />
                        </Dropdown.Toggle>
                        <Dropdown.Menu>
                            <Dropdown.Item
                                onClick={() =>
                                    handleEditOpen(info.row.original)
                                }
                                role="button"
                            >
                                Edit
                            </Dropdown.Item>
                            <Dropdown.Item
                                onClick={() => handleDelete(info.row.original)}
                            >
                                Delete
                            </Dropdown.Item>
                        </Dropdown.Menu>
                    </Dropdown>
                ),
            },
        ],
        [handleEditOpen, handleDelete],
    );

    // 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-wrap align-items-center justify-content-between gap-3">
                    <div className="d-flex flex-wrap align-items-center gap-2">
                        <div className="position-relative">
                            <Form.Control
                                type="search"
                                name="search"
                                value={searchValue}
                                onChange={handleSearch}
                                placeholder="Search..."
                                style={{ minWidth: "250px" }}
                            />
                        </div>
                    </div>
                    <div>
                        <Button
                            variant="success"
                            className="btn-icon-label"
                            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 Ref Lokasi" : "Tambah Ref Lokasi"}
                    </Modal.Title>
                </Modal.Header>

                <Modal.Body>
                    <Form>
                        <Row className="mb-3">
                            <Col md={6} className="mt-3">
                                <Form.Group>
                                    <Form.Label>Nama</Form.Label>
                                    <Form.Control
                                        type="text"
                                        value={data.name}
                                        placeholder="Masukkan Nama"
                                        onChange={(e) =>
                                            setData("name", e.target.value)
                                        }
                                        isInvalid={!!errors.name}
                                    />
                                    <Form.Control.Feedback type="invalid">
                                        {errors.name}
                                    </Form.Control.Feedback>
                                </Form.Group>
                            </Col>
                            <Col md={6} className="mt-3">
                                <Form.Group>
                                    <Form.Label>Unit Kerja (SKPD)</Form.Label>
                                    <Select
                                        options={skpdOptions}
                                        value={
                                            skpdOptions.find(
                                                (opt) =>
                                                    Number(opt.value) ===
                                                    Number(data.skpd_id),
                                            ) ?? null
                                        }
                                        onChange={(option: any) =>
                                            setData(
                                                "skpd_id",
                                                option ? option.value : null,
                                            )
                                        }
                                        styles={theme}
                                    />

                                    {errors.skpd_id && (
                                        <div className="invalid-feedback d-block">
                                            {errors.skpd_id}
                                        </div>
                                    )}
                                </Form.Group>
                            </Col>

                            <Col md={12}>
                                <Form.Label>Koordinat</Form.Label>
                                <Row className="mb-3 g-2">
                                    <Col md={5}>
                                        <Form.Control
                                            type="text"
                                            placeholder="Latitude"
                                            value={data.latitude}
                                            readOnly
                                        />
                                    </Col>
                                    <Col md={5}>
                                        <Form.Control
                                            type="text"
                                            placeholder="Longitude"
                                            value={data.longitude}
                                            readOnly
                                        />
                                    </Col>
                                    <Col md={2}>
                                        <Button
                                            variant="info"
                                            className="w-100"
                                            onClick={handleLokasiSaya}
                                        >
                                            <PiNavigationArrowFill /> Lokasi
                                            Saya
                                        </Button>
                                    </Col>
                                </Row>

                                <div style={{ height: "400px", width: "100%" }}>
                                    {isLoaded ? (
                                        <GoogleMap
                                            mapContainerStyle={{
                                                width: "100%",
                                                height: "100%",
                                            }}
                                            center={center}
                                            zoom={15}
                                            onClick={handleMapClick}
                                        >
                                            {data.latitude &&
                                                data.longitude && (
                                                    <Marker
                                                        position={{
                                                            lat: Number(
                                                                data.latitude,
                                                            ),
                                                            lng: Number(
                                                                data.longitude,
                                                            ),
                                                        }}
                                                    />
                                                )}
                                        </GoogleMap>
                                    ) : (
                                        <p>Loading Map...</p>
                                    )}
                                </div>
                                <small className="text-muted">
                                    Klik pada peta atau cari alamat di atas.
                                </small>
                            </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>
    );
}
