"use client";
import { InnerCard } from "@/components/menu-slider";
import { Person } from "@/components/tanstack-table/makeData";
import { getCustomerTableColumns } from "@/constant";
import useColumnVisibility from "@/hooks/useColumnVisibility";
import usePagination from "@/hooks/usePagination";
import useRowSelection from "@/hooks/useRowSelection";
import useTable from "@/hooks/useTable";
import Axios from "@/lib/Axios";
import useMenuSliderStore from "@/store/useMenuSliderStore";
import { CustomerDataT } from "@/types/customer";
import { PaginationStructT } from "@/types/global";
import { UserListT } from "@/types/user";
import { useMutation, useQuery } from "@tanstack/react-query";
import React, { useEffect, useMemo, useState, useRef, useCallback } from "react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Check, Filter, FilterX, Loader, Plus } from "lucide-react";
import { Input } from "@/components/ui/input";
import useGlobalSearchStore from "@/store/useGlobalSearchStore";
import { useDebounce } from "use-debounce";
import { useCustomerStore } from "@/store/useCustomerStore";
import { Combobox } from "@/components/combobox";
import { SearchReportTo } from "@/components/pages/add-emp/searchReportTo";
import { toast } from "@/components/ui/use-toast";
import { AxiosError, AxiosResponse } from "axios";
import { RespError } from "@/types/auth";
import { cn } from "@/lib/utils";
import { useRouter } from "next/navigation";
import useUserStore from "@/store/useUserStore";

type TableHydrateT = {
  offset: number;
  limit: number;
  initData?: PaginationStructT<UserListT[]> | null;
};

const fallBack: any[] = [];

export default function CustomerTable({
  offset = 0,
  limit = 10, // This is now ignored for fetching, but can be used for initial visible count
  initData,
}: TableHydrateT) {
  const { pagination, setPagination } = usePagination(
    Number(offset),
    Number(limit)
  );
  const { rowSelection, setRowSelection } = useRowSelection();
  const [_, setData] = React.useState<Person[]>(() => []);

  const { gSearch, setGSearch } = useGlobalSearchStore();
  const [scope, setScope] = useState<string[]>([]);
  const [debouncedSearchQuery] = useDebounce(gSearch, 500);
  const [debouncedScopeQuery] = useDebounce(scope, 500);

  const [allData, setAllData] = useState<CustomerDataT[]>([]);
  const [visibleCount, setVisibleCount] = useState(10); // Show 30 initially
  const tableContainerRef = useRef<HTMLDivElement>(null);
  const [isLoading, setIsLoading] = useState(true);

  const { columnVisibility, setColumnVisibility } = useColumnVisibility();
  const { columns } = useMemo(
    () => getCustomerTableColumns(async () => {}),
    []
  );

  const tableData = useMemo(() => allData ?? fallBack, [allData]);
  const { setInnerElement, setOptionsElement, open } = useMenuSliderStore();
  const { customers, setCustomers } = useCustomerStore();

  useEffect(() => {
    console.log(rowSelection);
    setCustomers(Object.keys(rowSelection).map(Number));
  }, [rowSelection]);
    const router = useRouter();

  const rowHandler = ({ id }: CustomerDataT) => {
    // setColumnVisibility({
    //   action: false,
    // });
    // setInnerElement(CustomerMenuDetails(data, refetch));
    // setOptionsElement(Options(data));
    // MenuSliderHandler();
    // setColumnVisibility({
    //   action: true,
    // });
  };

  // Fetch all customers once on mount
  useEffect(() => {
    async function fetchAllCustomers() {
      setIsLoading(true);
      try {
        const resp = await Axios.get<PaginationStructT<CustomerDataT[]>>("/customer/management/", {
          params: {
            offset: 0,
            limit: 10000, // Large number to fetch all
          },
        });
        setAllData(resp.data.data || []);
      } catch (e) {
        // Optionally handle error
      } finally {
        setIsLoading(false);
      }
    }
    fetchAllCustomers();
  }, []);

  // Scroll handler to reveal more items
  useEffect(() => {
    const container = tableContainerRef.current;
    if (!container) return;
    const handleScroll = () => {
      if (
        container.scrollTop + container.clientHeight >=
        container.scrollHeight - 100
      ) {
        setVisibleCount((prev) => Math.min(prev + 10, allData.length));
      }
    };
    container.addEventListener("scroll", handleScroll);
    return () => container.removeEventListener("scroll", handleScroll);
  }, [allData.length]);

  // Reset visibleCount if search/filter changes (optional, if you add search)
  // useEffect(() => { setVisibleCount(30); }, [search/filter state]);

  type Filter = {
    key: string;
    name?: string;
  };

  const filters: Filter[] = [
    {
      key: "first_name",
      name: "First Name",
    },
    {
      key: "last_name",
      name: "Last Name",
    },
    {
      key: "email",
      name: "Email",
    },
    {
      key: "mobile_phone",
      name: "Mobile Phone",
    },
    {
      key: "home_phone",
      name: "Home Phone",
    },
    {
      key: "assigned_to__user__name",
      name: "Assigned to",
    },
    {
      key: "created_by",
      name: "Created By",
    },
    {
      key: "id",
      name: "Customer Id",
    },
    {
      key: "address__post_code",
      name: "Postal code",
    },
  ];

  // Add filteredData for search
  const filteredData = useMemo(() => {
    if (!debouncedSearchQuery) return allData;
    const lower = debouncedSearchQuery.toLowerCase();
    return allData.filter(row =>
      (scope.length ? scope : filters.map(f => f.key)).some(key => {
        // Support nested keys (e.g., address__post_code)
        const value = key.split("__").reduce((acc, k) => acc?.[k], row as any);
        return value && String(value).toLowerCase().includes(lower);
      })
    );
  }, [allData, debouncedSearchQuery, scope]);

  const { Table, table } = useTable({
    setPagination,
    pagination,
    columns,
    data: filteredData.slice(0, visibleCount), // Only show visibleCount items
    setData,
    rowSelection,
    setRowSelection,
    columnVisibility,
    setColumnVisibility,
    onRowClick: rowHandler,
    rowCount: filteredData.length,
  });

  useEffect(() => {}, [columnVisibility]);

  const [isFilterOpen, setFilterOpenState] = useState<boolean>(false);

  return (
    <div className="w-full" ref={tableContainerRef} style={{ maxHeight: "70vh", overflowY: "auto" }}>
      <div className="my-5 flex gap-1 items-center justify-between">
        <div className="flex gap-2">
          <Link href="/customer/customer-manage">
            <Button className="bg-brownish hover:bg-yellowish">
              <p className="mr-2">Add Customer</p> <Plus />
            </Button>
          </Link>

          <div className="ml-10 w-96 space-y-2">
            <div className="flex items-center border-2 rounded-md">
              <Input
                className="border-none"
                placeholder="search"
                onChange={(e) => setGSearch(e.currentTarget.value)}
              />
              <div
                onClick={() => setFilterOpenState(!isFilterOpen)}
                className="bg-brownish p-2 rounded-md text-white cursor-pointer select-none"
              >
                {!isFilterOpen ? <Filter /> : <FilterX />}
              </div>
            </div>
            {isFilterOpen ? (
              <div className="flex flex-wrap gap-1">
                {filters.map(({ name, key }, i) => (
                  <Chip
                    key={i}
                    name={name ?? ""}
                    onSelectChange={(isSelected) => {
                      if (isSelected) setScope((prev) => [...prev, key]);
                      else setScope((prev) => prev.filter((i) => i !== key));
                    }}
                  />
                ))}
              </div>
            ) : null}
          </div>
        </div>

        {customers && customers.length != 0 ? (
          <InnerCard>
            <p className="text-danger text-xl underline mb-2">Assign to</p>
            <AssignToOption
              customers={customers}
              reset={() => setRowSelection({})}
            />
          </InnerCard>
        ) : null}
      </div>
      <div className="relative">
        {isLoading ? (
          <div className="text-center py-2">Loading...</div>
        ) : (
          <Table />
        )}
        {visibleCount < allData.length && !isLoading && (
          <div className="text-center py-2"></div>
        )}
      </div>
    </div>
  );
}

interface ChipProps {
  name: string;
  onSelectChange: (val: boolean) => void;
}

function Chip({ name, onSelectChange }: ChipProps) {
  const [isSelected, setSelected] = useState<boolean>(false);

  useEffect(() => {
    console.log("::HELLO::", "SOME SELECTION IS CHANGED");
    onSelectChange(isSelected);
  }, [isSelected]);

  function handleSelected(
    event: React.MouseEvent<HTMLDivElement, MouseEvent>
  ): void {
    setSelected(!isSelected);
  }

  return (
    <div
      className={cn(
        "border-brownish border-2 text-brownish text-xs px-2 py-1 rounded-md cursor-pointer select-none focus-visible:bg-white"
      )}
      onClick={handleSelected}
    >
      <div className="flex space-x-1">
        {isSelected ? <Check size={15} /> : null}
        <span>{name}</span>
      </div>
    </div>
  );
}

function AssignToOption({
  customers,
  reset,
}: {
  customers: number[];
  reset: () => void;
}) {
  const { setCustomers } = useCustomerStore();

  const mutationSend = useMutation<
    AxiosResponse<any>,
    AxiosError<RespError>,
    any
  >({
    mutationFn: sendData,
    onSuccess: (data) => {
      toast({
        title: "Success",
        description: "Customer has been saved successfully",
      });
      setCustomers([]);
      reset();
    },
    onError: (error) => {
      const errorObj: Record<any, string[]> = error.response?.data.data!;
      let message = "";
      for (let key in errorObj) {
        if (errorObj.hasOwnProperty(key)) {
          let value = errorObj[key];
          message += key + " " + value[0] + "\n";
        }
      }
      toast({
        variant: "destructive",
        title: "Error",
        description: message,
      });
    },
  });

  function sendData(id?: number) {
    const data = {
      customer_ids: customers,
      assigned_to_id: id,
    };

    return Axios.patch("/customer/management/bulk_assign/", data);
  }

  return (
    <div className="flex items-center gap-2">
      <Combobox<UserListT>
        placeholder={"Assign to"}
        onSelect={(e) => {
          console.log(e);
          if (e === null) {
            return;
          }
          mutationSend.mutate(e.id);
        }}
      >
        <SearchReportTo />
      </Combobox>
      {mutationSend.isPending && (
        <Loader className="text-white animate-spin " />
      )}
    </div>
  );
}