import { useState, useEffect, useMemo, useCallback } from "react";
import React from "react";
import HeaderSection from "../headerSection";
import { t } from "i18next";
import { useSearchParams } from "react-router-dom";

import { DataTable } from "@/record-management/common/DataTable";
import { Button } from "@/shared/common/ui/button";
import {
  CombinedFilterBar,
  CombinedFilterField,
} from "@/shared/components/filters/CombinedFilterBar";
import { useCCIncomingRecords } from "@/record-management/components/hooks/useCCIncomingRecords";
import { CCIncomingRecordsColumns } from "../ccIncomingRecords/ccIncomingRecordsColumns";
import Loader from "@/record-management/components/Loader/loader";
import { useLocalizedName } from "@/shared/common/localizedName";
import { useAuthUser } from "@/shared/hooks/useAuthUser";
import { useCombinedFilters } from "@/shared/hooks/useCombinedFilters";
import { useUserDetail } from "../../hooks/useUserDetail";
import { MeDto } from "@/shared/dto/user/meDto";
import secretaryList from "@/record-management/common/secretaryViewList";
import DelegationView from "@/record-management/common/DelegationView";
import useCanAssignRecord from "../../hooks/useCanAssignRecord";
import { FilterParams } from "@/shared/utils/filterParams";

const ForYourReferenceIncomingRecords = () => {
  const [statusFilter, setStatusFilter] = useState<string>("");
  const localizedName = useLocalizedName();
  const { userDetails } = useAuthUser();
  const { permissionKeys } = useUserDetail(userDetails as MeDto);
  const isSecretary = permissionKeys.includes("can:viewParentPositionRecord");
  const selfFilters = useCombinedFilters<FilterParams>();
  const parentFilters = useCombinedFilters<FilterParams>();
  const [searchParamsUrl, setSearchParamsUrl] = useSearchParams();
  const urlPage = Number(searchParamsUrl.get("page") || 1);
  const initialView = searchParamsUrl.get("view") || "self";
  const [secretaryView, setSecretaryView] = useState(isSecretary ? initialView : "self");
  const [pagination, setPagination] = React.useState({
    pageIndex: urlPage - 1,
    pageSize: 10,
  });

  useEffect(() => {
    if (!isSecretary && secretaryView === "parent") {
      setSecretaryView("self");
    }
  }, [isSecretary, secretaryView]);
  const [liveSearch, setLiveSearch] = useState<{
    key: string;
    value: string;
  } | null>(null);

  const handleLiveSearch = (key: string, value: string) => {
    if (!key || !value) {
      setLiveSearch(null);
      return;
    }
    setLiveSearch({ key, value });
  };
  const isDelegated = userDetails?.employee?.some((emp) =>
    emp.positions.some((pos) => pos.hasDelegated),
  );
  const isSelf = secretaryView === "self";
  const syncViewParam = useCallback((params: URLSearchParams) => {
    if (secretaryView === "parent") {
      params.set("view", "parent");
    } else {
      params.delete("view");
    }
    return params;
  }, [secretaryView]);
  const { canAssignRecord: canAssignCC } = useCanAssignRecord();
  const activeFilterStore = isSelf ? selfFilters : parentFilters;

  const filterFields = useMemo<CombinedFilterField[]>(
    () => [
      {
        key: "sendingPosition",
        label: t("userIncoming.Department"),
        type: "text",
      },
      { key: "subject", label: t("userIncoming.Subject"), type: "text" },
      {
        key: "referenceNumber",
        label: t("viewDetail.referenceNumber"),
        type: "text",
      },
      {
        key: "dispatchedDate",
        label: t("userIncoming.Date"),
        type: "dateRange",
        fromKey: "fromDispatchedDate",
        toKey: "toDispatchedDate",
      },
    ],
    [],
  );

  useEffect(() => {
    setSearchParamsUrl(
      (prev) => syncViewParam(new URLSearchParams(prev)),
      { replace: true },
    );
  }, [secretaryView, setSearchParamsUrl, syncViewParam]);

  React.useEffect(() => {
    setPagination((prev) => ({ ...prev, pageIndex: urlPage - 1 }));
  }, [activeFilterStore.filters, statusFilter, urlPage]);

  const mapStatusToHasSeen = (status: string): boolean | undefined => {
    if (status === "seen") return true;
    return undefined;
  };

  const baseParams = {
    skip: pagination.pageIndex * pagination.pageSize,
    take: pagination.pageSize,
    orderBy: "record.dispatchedDate:DESC,record.createdAt:DESC",
    hasSeen: mapStatusToHasSeen(statusFilter),
    isForYourReference: true,
    ...activeFilterStore.filters,
    fetchParent: isSecretary,
    ...(liveSearch ? { [liveSearch.key]: liveSearch.value } : {}),
  };

  const statusOptions = [
    { value: "", label: t("statusBar.All") },
    { value: "draft", label: t("statusBar.InProgress") },
    { value: "seen", label: t("statusBar.seen") },
  ];

  const {
    ccRecords,
    isLoading,
    isError,
    ccCount,
    refetch,
    ccParent,
    ccParentCount,
    refetchParent,
    isErrorParent,
    isLoadingParent,
  } = useCCIncomingRecords(baseParams);

  let Error, loading;
  if (isSelf) {
    Error = isError;
    loading = isLoading;
  } else {
    Error = isErrorParent;
    loading = isLoadingParent;
  }

  const safeTotalCount = Math.max(
    isSelf ? ccCount || 0 : ccParentCount || 0,
    1,
  );

  const totalPages = Math.ceil(safeTotalCount / pagination.pageSize);

  useEffect(() => {
    setLiveSearch(null);
  }, [secretaryView]);

  React.useEffect(() => {
    if (safeTotalCount === 1) return;
    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,
  ]);

  return isDelegated ? (
    <DelegationView />
  ) : (
    <div className="flex flex-col gap-2">
      <div className="mt-4 flex w-full min-w-0 flex-col gap-4">
        <h4 className="text-xl font-medium text-gray-900 dark:text-gray-100">
          {t("userIncoming.Letters")}
        </h4>
        <CombinedFilterBar
          fields={filterFields}
          filters={activeFilterStore.filters}
          setFilter={activeFilterStore.setFilter}
          setFilters={activeFilterStore.setFilters}
          removeFilter={activeFilterStore.removeFilter}
          removeFilters={activeFilterStore.removeFilters}
          onFilterChange={() =>
            setPagination((prev) => ({ ...prev, pageIndex: 0 }))
          }
          onLiveSearch={handleLiveSearch}
          className="w-full min-w-0"
        />
      </div>

      <HeaderSection />
      {secretaryList(isSecretary, secretaryView, setSecretaryView, "SEC")}

      <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>

      {loading && (
        <div className="w-full h-full">
          <Loader />
        </div>
      )}
      {Error && isDelegated && <p>{t("userIncoming.errDelegation")}</p>}
      {Error && !isDelegated && (
        <p>{t("userIncoming.Error loading records.")}</p>
      )}

      {!loading && !Error && (
        <DataTable
          tableName="For Your Reference Records"
          columns={CCIncomingRecordsColumns(
            isSelf ? refetch : refetchParent ? refetchParent : () => {},
            localizedName as (name?: { am?: string; en?: string }) => string,
            isSecretary,
            isSelf,
            pagination.pageIndex + 1,
            false,
            canAssignCC,
            "ForYourReference",
          )}
          data={isSelf ? ccRecords : ccParent ? ccParent : []}
          toolBarPosition="right"
          totalCount={safeTotalCount}
          pagination={pagination}
          setPagination={setPagination}
          refresh={isSelf ? refetch : refetchParent}
        />
      )}
    </div>
  );
};

export default ForYourReferenceIncomingRecords;
