import { useState, useEffect, useMemo, useCallback } from "react";
import { DataTable } from "@/record-management/common/DataTable";
import { Button } from "@/shared/common/ui/button";
import { Input } from "@/shared/common/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";
import { useInternalIncomingRecords } from "@/record-management/components/hooks/useInternalIncomingRecords";
import { Search } from "lucide-react";
import Loader from "@/record-management/components/Loader/loader";
import React from "react";
import HeaderSection from "../headerSection";
import { useTranslation } from "react-i18next";

import { useLocalizedName } from "@/shared/common/localizedName";
import { useAuthUser } from "@/shared/hooks/useAuthUser";
import { useUserDetail } from "../../hooks/useUserDetail";
import { MeDto } from "@/shared/dto/user/meDto";
import { useSearchParams } from "react-router-dom";
import secretaryList from "@/record-management/common/secretaryViewList";
import DelegationView from "@/record-management/common/DelegationView";
import EthiopianDatePickerModal, {
  convertEthiopianToGregorian,
} from "@/shared/common/form/fields/AmharicDatePicker";
import i18n from "@/i18n";
import { InternalIncomingRecordsColumnsV2 } from "./incomingInternalRecordsColumnsV2";
import { IncomingLetterItem } from "@/record-management/dto/IncomingRecords/incomingTasksDto";
import AssignRecordV2 from "./AssignRecordV2";
import { useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";

const InternalIncomingRecordsV2 = () => {
  const localizedName = useLocalizedName();
  const { t } = useTranslation();
  const queryClient = useQueryClient();
  const { userDetails } = useAuthUser();
  const { permissionKeys } = useUserDetail(userDetails as MeDto);
  const lang = i18n.language;
  const [showFromPicker, setShowFromPicker] = useState(false);
  const [showToPicker, setShowToPicker] = useState(false);
  // Filters & pagination
  const [statusFilter, setStatusFilter] = useState<string>("");
  const [searchQuery, setSearchQuery] = useState("");
  const [searchQuerySec, setSearchQuerySec] = useState("");
  const [filterType, setFilterType] = useState<
    "Department" | "Subject" | "Dispatched Date" | "Reference Number"
  >("Department");
  const [fromDispatchedDate, setFromDispatchedDate] = useState("");
  const [toDispatchedDate, setToDispatchedDate] = useState("");
  const [fromDispatchedDateDisplay, setFromDispatchedDateDisplay] =
    useState("");
  const [toDispatchedDateDisplay, setToDispatchedDateDisplay] = useState("");
  const isSecretary = permissionKeys.includes("can:viewParentPositionRecord");
  const [searchParamsUrl, setSearchParamsUrl] = useSearchParams();
  const urlPage = Number(searchParamsUrl.get("page") || 1);
  const initialView = searchParamsUrl.get("view") || "self";
  const [pagination, setPagination] = useState({
    pageIndex: urlPage - 1,
    pageSize: 10,
  });
  const isDelegated = userDetails?.employee?.some((emp) =>
    emp.positions.some((pos) => pos.hasDelegated),
  );
  const [secretaryView, setSecretaryView] = useState(isSecretary ? initialView : "self");
  const [openDropdownId, setOpenDropdownId] = useState<string | null>(null);
  const [assignRecord, setAssignRecord] = useState<IncomingLetterItem | null>(
    null,
  );

  useEffect(() => {
    if (!isSecretary && secretaryView === "parent") {
      setSecretaryView("self");
    }
  }, [isSecretary, secretaryView]);

  const isSelf = secretaryView === "self";
  const syncViewParam = useCallback((params: URLSearchParams) => {
    if (secretaryView === "parent") {
      params.set("view", "parent");
    } else {
      params.delete("view");
    }
    return params;
  }, [secretaryView]);
  useEffect(() => {
    setSearchParamsUrl(
      (prev) => syncViewParam(new URLSearchParams(prev)),
      { replace: true },
    );
  }, [secretaryView, setSearchParamsUrl, syncViewParam]);

  // Snap back to page 1 whenever any filter changes
  useEffect(() => {
    setPagination((prev) => ({ ...prev, pageIndex: 0 }));
    setSearchParamsUrl(
      (prev) => {
        const params = new URLSearchParams(prev);
        params.set("page", "1");
        return syncViewParam(params);
      },
      { replace: true },
    );
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    statusFilter,
    searchQuery,
    searchQuerySec,
    filterType,
    fromDispatchedDate,
    toDispatchedDate,
    syncViewParam,
  ]);

  // Honour external URL page changes (deep links, back/forward)
  useEffect(() => {
    setPagination((prev) =>
      prev.pageIndex === urlPage - 1
        ? prev
        : { ...prev, pageIndex: urlPage - 1 },
    );
  }, [urlPage]);
  // Map filterType + searchQuery to backend parameters
  const searchParams: Record<string, string> = {};
  if (isSelf ? searchQuery : searchQuerySec) {
    switch (filterType) {
      case "Department":
        searchParams.sendingPosition = isSelf ? searchQuery : searchQuerySec;
        break;
      case "Subject":
        searchParams.subject = isSelf ? searchQuery : searchQuerySec;
        break;
      case "Reference Number":
        searchParams.referenceNumber = isSelf ? searchQuery : searchQuerySec;
        break;
    }
  }

  // Add dispatched date filter if set
  if (fromDispatchedDate) searchParams.fromDispatchedDate = fromDispatchedDate;
  if (toDispatchedDate) searchParams.toDispatchedDate = toDispatchedDate;

  const {
    isLoadingV2: isLoading,
    isErrorV2: isError,
    refetchV2,
    internalRecords2,
    InternalCount2,
    internalParent,
    internalParentCount,
    refetchParent,
    isErrorParent,
    isLoadingParent,
  } = useInternalIncomingRecords({
    pageIndex: pagination.pageIndex * pagination.pageSize,
    pageSize: pagination.pageSize,
    status: statusFilter || undefined,
    ...searchParams,
    fetchParent: isSecretary,
  });
  let Error, loading;
  if (isSelf) {
    Error = isError;
    loading = isLoading;
  } else {
    Error = isErrorParent;
    loading = isLoadingParent;
  }
  const refetchCurrent = useCallback(() => {
    if (isSelf) {
      refetchV2();
    } else {
      refetchParent?.();
    }
  }, [isSelf, refetchV2, refetchParent]);

  const handleAssignRecord = useCallback((record: IncomingLetterItem) => {
    setAssignRecord(record);
  }, []);

  const statusOptions = [
    { value: "", label: t("statusBar.All") },
    { value: "draft", label: t("statusBar.In Progress") },
    { value: "accepted", label: t("statusBar.Accepted") },
    { value: "replied", label: t("statusBar.Replied") },
    { value: "re_assigned", label: t("statusBar.Reassigned") },
    { value: "rejected", label: t("statusBar.Rejected") },
  ];
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    (isSelf ? setSearchQuery : setSearchQuerySec)(e.target.value);
  };

  useEffect(() => {
    if (isSelf) refetchV2();
    else {
    }
  }, [
    pagination.pageIndex,
    pagination.pageSize,
    statusFilter,
    searchQuery,
    filterType,
    fromDispatchedDate,
    toDispatchedDate,
    refetchV2,
    isSelf,
  ]);
  const safeTotalCount = Math.max(
    isSelf ? InternalCount2 || 0 : internalParentCount || 0,
    1,
  );
  const totalPages = Math.ceil(safeTotalCount / pagination.pageSize);

  React.useEffect(() => {
    if (safeTotalCount === 1) return; // wait until data is loaded

    let newPage = pagination.pageIndex + 1;

    if (newPage > totalPages) {
      newPage = 1;
      setPagination((prev) => ({ ...prev, pageIndex: 0 }));
    }

    setSearchParamsUrl((prev) => {
      const params = new URLSearchParams(prev);
      params.set("page", newPage.toString());
      return syncViewParam(params);
    });
  }, [
    totalPages,
    safeTotalCount,
    pagination.pageIndex,
    setSearchParamsUrl,
    syncViewParam,
  ]);
  const columns = useMemo(
    () =>
      InternalIncomingRecordsColumnsV2(
        isSelf ? refetchV2 : refetchParent ? refetchParent : () => {},
        localizedName,
        isSecretary,
        isSelf,
        pagination?.pageIndex + 1,
        openDropdownId,
        setOpenDropdownId,
        handleAssignRecord,
      ),
    [
      refetchV2,
      refetchParent,
      localizedName,
      isSecretary,
      isSelf,
      pagination,
      openDropdownId,
      setOpenDropdownId,
      handleAssignRecord,
    ],
  );
  return isDelegated ? (
    <DelegationView />
  ) : (
    <div className="flex flex-col gap-2 bg-background text-foreground">
      {/* Header + Filter */}
      <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 w-full mt-4">
        <h4 className="text-xl font-medium mt-2 text-gray-900 dark:text-gray-100">
          {t("userIncoming.Letters")}
        </h4>

        <div className="flex flex-col sm:flex-row items-start sm:items-center gap-2 w-full sm:w-auto">
          {/* Filter Dropdown */}
          <Select
            value={filterType}
            onValueChange={(value) => {
              return setFilterType(
                value === "referenceNumber"
                  ? "Reference Number"
                  : value === "dispatchedDate"
                    ? "Dispatched Date"
                    : (value as
                        | "Department"
                        | "Subject"
                        | "Dispatched Date"
                        | "Reference Number"),
              );
            }}
          >
            <SelectTrigger className="w-full sm:w-[200px]">
              <SelectValue placeholder="Select filter type" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="Department">
                {t("userIncoming.Department")}
              </SelectItem>
              <SelectItem value="Subject">
                {t("userIncoming.Subject")}
              </SelectItem>
              <SelectItem value="Dispatched Date">
                {t("userIncoming.Dispatched Date")}
              </SelectItem>
              <SelectItem value="Reference Number">
                {t("userIncoming.Reference Number")}
              </SelectItem>
            </SelectContent>
          </Select>

          {/* Search Input */}
          {filterType !== "Dispatched Date" ? (
            <div className="relative w-full sm:w-[200px]">
              <div className="absolute left-2 top-1/2 transform -translate-y-1/2 pointer-events-none">
                <Search className="h-4 w-4 text-gray-500" />
              </div>
              <Input
                className="w-full pl-8 text-sm sm:text-base"
                type="text"
                placeholder={`${t(
                  "userIncoming.Search",
                )} ${filterType.toLowerCase()}`}
                value={isSelf ? searchQuery : searchQuerySec}
                onChange={handleSearchChange}
              />
            </div>
          ) : (
            <div className="flex flex-col sm:flex-row gap-2">
              {lang.startsWith("en") ? (
                <>
                  <label className="mt-2">From: </label>
                  <Input
                    type="date"
                    value={fromDispatchedDate}
                    onChange={(e) => setFromDispatchedDate(e.target.value)}
                    className="w-[150px]"
                  />
                  <label className="mt-2">To: </label>
                  <Input
                    type="date"
                    value={toDispatchedDate}
                    onChange={(e) => setToDispatchedDate(e.target.value)}
                    min={fromDispatchedDate}
                    className="w-[150px]"
                  />
                </>
              ) : (
                <div className="flex flex-wrap items-center gap-3">
                  {/* From Date */}
                  <div className="relative">
                    <label className="font-medium mr-2">ከ:</label>
                    <input
                      type="text"
                      value={fromDispatchedDateDisplay}
                      readOnly
                      onClick={() => setShowFromPicker((prev) => !prev)}
                      className="border border-gray-300 dark:border-gray-700 rounded-md px-2 py-1.5 w-40 bg-white dark:bg-gray-800 cursor-pointer"
                      placeholder="ቀን ይምረጡ"
                    />
                    {showFromPicker && (
                      <div className="absolute z-50 mt-1 bg-white dark:bg-gray-800 shadow-lg rounded-md p-2">
                        <EthiopianDatePickerModal
                          value={fromDispatchedDate}
                          onChange={(ethiopianDate: string) => {
                            const gregorianDate =
                              convertEthiopianToGregorian(ethiopianDate);
                            const formatted = gregorianDate
                              .toISOString()
                              .split("T")[0]; // "YYYY-MM-DD"
                            setFromDispatchedDate(formatted);
                            setFromDispatchedDateDisplay(ethiopianDate);
                            setShowFromPicker(false);
                          }}
                        />
                      </div>
                    )}
                  </div>

                  {/* To Date */}
                  <div className="relative">
                    <label className="font-medium mr-2">እስከ:</label>
                    <input
                      type="text"
                      value={toDispatchedDateDisplay}
                      readOnly
                      onClick={() => setShowToPicker((prev) => !prev)}
                      className="border border-gray-300 dark:border-gray-700 rounded-md px-2 py-1.5 w-40 bg-white dark:bg-gray-800 cursor-pointer"
                      placeholder="ቀን ይምረጡ"
                    />
                    {showToPicker && (
                      <div className="absolute z-50 mt-1 bg-white dark:bg-gray-800 shadow-lg rounded-md p-2">
                        <EthiopianDatePickerModal
                          value={toDispatchedDate}
                          onChange={(ethiopianDate: string) => {
                            const gregorianDate =
                              convertEthiopianToGregorian(ethiopianDate);
                            const formatted = gregorianDate
                              .toISOString()
                              .split("T")[0]; // "YYYY-MM-DD"
                            setToDispatchedDate(formatted);
                            setToDispatchedDateDisplay(ethiopianDate);
                            setShowFromPicker(false);
                          }}
                        />
                      </div>
                    )}
                  </div>
                </div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* Navigation Buttons */}
      <HeaderSection />
      {/* secretary options */}
      {secretaryList(isSecretary, secretaryView, setSecretaryView, "SEC")}
      {/* Status Buttons */}
      <div className="flex flex-wrap gap-2">
        {statusOptions.map((option) => (
          <Button
            key={option.value}
            variant={statusFilter === option.value ? "linkActive" : "link"}
            onClick={() => setStatusFilter(option.value)}
            className="rounded-md text-sm sm:text-base"
          >
            {option.label}
          </Button>
        ))}
      </div>

      {/* Records Table */}
      {loading && (
        <div className="w-full h-full">
          <Loader />
        </div>
      )}
      {Error && isDelegated && (
        <p className="text-red-600 dark:text-red-400">
          {t("userIncoming.errDelegation")}
        </p>
      )}
      {Error && !isDelegated && (
        <p className="text-red-600 dark:text-red-400">
          {t("userIncoming.Error loading records.")}
        </p>
      )}
      {!loading && !Error && (
        <>
          <DataTable
            tableName="Internal Incoming Records V2"
            columns={columns}
            data={isSelf ? internalRecords2 : internalParent ?? []}
            totalCount={isSelf ? InternalCount2 : internalParentCount ?? 0}
            pagination={pagination}
            setPagination={setPagination}
            toolBarPosition="right"
            refresh={isSelf ? refetchV2 : refetchParent}
          />

          {assignRecord && !assignRecord.isLocked && (
            <AssignRecordV2
              record={assignRecord}
              isTable={true}
              isOpen
              onClose={() => {
                setAssignRecord(null);
              }}
              onSuccess={() => {
                toast.success(t("msg.successassign"));
                setAssignRecord(null);
                refetchCurrent();
                queryClient.invalidateQueries({
                  queryKey: ["incoming-instances"],
                });
                queryClient.invalidateQueries({
                  queryKey: ["incoming-instances/v2"],
                });
                queryClient.invalidateQueries({
                  queryKey: ["dashbordReport"],
                });
              }}
            />
          )}
        </>
      )}
    </div>
  );
};

export default InternalIncomingRecordsV2;
