import * as React from "react";
import { useTranslation } from "react-i18next";
import { useNavigate, useSearchParams } from "react-router-dom";
import { CirclePlus, Search, X } from "lucide-react";
import { useQueryClient } from "@tanstack/react-query";

import { useUserRecords } from "../hooks/useUserRecords";
import { UserRecordsColumns } from "./userRecordsColumns";
import Loader from "../../components/Loader/loader";

import {
  Select,
  SelectTrigger,
  SelectContent,
  SelectItem,
  SelectValue,
} from "@/shared/common/ui/select";
import { Input } from "@/shared/common/ui/input";
import { Button } from "@/shared/common/ui/button";
import { Badge } from "@/shared/common/ui/badge";
import { AdvancedTable } from "@/shared/common/ui/table/AdvancedTable";
import { useLocalizedName } from "@/shared/common/localizedName";
import { useAuthUser } from "@/shared/hooks/useAuthUser";
import { useCombinedFilters } from "@/shared/hooks/useCombinedFilters";
import { useUserDetail } from "../hooks/useUserDetail";
import { useState } from "react";
import { MeDto } from "@/shared/dto/user/meDto";
import secretaryList from "@/record-management/common/secretaryViewList";
import DelegationView from "@/record-management/common/DelegationView";
import { cn } from "@/shared/lib/utils";
import i18n from "@/i18n";
import EthiopianDatePickerModal, {
  convertEthiopianToGregorian,
} from "@/shared/common/form/fields/AmharicDatePicker";
import { useUnitConfiguration } from "@/shared/hooks/useUnitConfiguration";
import ApproveRecord from "./approveRecord";
import { RecordDto } from "@/record-management/dto/userRecords/userRecordsDto";
import { cleanFilterParams } from "@/shared/utils/filterParams";

type Filters = {
  receiverPosition?: string;
  receiverEmployee?: string;
  receiverUnit?: string;
  subject?: string;
  referenceNumber?: string;
  letterName?: string;
  fromCreatedAt?: string;
  toCreatedAt?: string;
};

type TextFilterKey = Exclude<keyof Filters, "fromCreatedAt" | "toCreatedAt">;
type FilterConfig =
  | {
      key: TextFilterKey;
      label: string;
      type: "text";
    }
  | {
      key: "createdAt";
      label: string;
      type: "dateRange";
      fromKey: "fromCreatedAt";
      toKey: "toCreatedAt";
    };

type ActiveFilterChip = {
  key: string;
  label: string;
  value: string;
  remove: () => void;
};

const UserRecords = () => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const localizedName = useLocalizedName();
  const [searchParams, setSearchParams] = useSearchParams();
  const urlPage = Number(searchParams.get("page") || 1);
  const initialView = searchParams.get("view") || "self";

  const [pageIndex, setPageIndex] = React.useState(urlPage - 1);
  const pageSize = 10;
  const { userDetails } = useAuthUser();
  const isDelegated = userDetails?.employee?.some((emp) =>
    emp.positions.some((pos) => pos.hasDelegated),
  );

  const [statusFilter, setStatusFilter] = React.useState("All");
  const [menuFilter, setMenuFilter] = React.useState("All");
  const [showFromPicker, setShowFromPicker] = useState(false);
  const [showToPicker, setShowToPicker] = useState(false);
  const [approveTarget, setApproveTarget] = useState<RecordDto | null>(null);
  const [selectedFilterKey, setSelectedFilterKey] =
    React.useState<FilterConfig["key"]>("receiverPosition");
  const [filterInputValue, setFilterInputValue] = React.useState("");
  const [liveSearch, setLiveSearch] = React.useState<{
    key: string;
    value: string;
  } | null>(null);
  const [openDropdownId, setOpenDropdownId] = useState<string | null>(null);
  const selfFilters = useCombinedFilters<Filters>();
  const parentFilters = useCombinedFilters<Filters>();
  const [fromDate, setFromDate] = React.useState<string>("");
  const [toDate, setToDate] = React.useState<string>("");
  const [fromDateDisplay, setFromDateDisplay] = React.useState<string>("");
  const [toDateDisplay, setToDateDisplay] = React.useState<string>("");
  const { permissionKeys } = useUserDetail(userDetails as MeDto);
  const isSecretary = permissionKeys.includes("can:viewParentPositionRecord");
  const [secretaryView, setSecretaryView] = useState(isSecretary ? initialView : "self");
  const lang = i18n.language;
  const isSelf = secretaryView === "self";

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

  const filterFields = React.useMemo<FilterConfig[]>(
    () => [
      {
        key: "receiverPosition",
        label: t("userRecord.ReceiverPosition"),
        type: "text",
      },
      {
        key: "receiverEmployee",
        label: t("userRecord.ReceiverEmployee"),
        type: "text",
      },
      {
        key: "receiverUnit",
        label: t("userRecord.ReceiverUnit"),
        type: "text",
      },
      { key: "subject", label: t("userRecord.Subject"), type: "text" },
      {
        key: "createdAt",
        label: t("userRecord.Date"),
        type: "dateRange",
        fromKey: "fromCreatedAt",
        toKey: "toCreatedAt",
      },
      {
        key: "referenceNumber",
        label: t("userRecord.Reference"),
        type: "text",
      },
      { key: "letterName", label: t("viewDetail.fileName"), type: "text" },
    ],
    [t],
  );

  const activeFilterStore = isSelf ? selfFilters : parentFilters;
  const activeFilters = activeFilterStore.filters;

  const isFilterActive = React.useCallback(
    (field: FilterConfig) => {
      if (field.type === "dateRange") {
        return Boolean(
          activeFilters[field.fromKey] || activeFilters[field.toKey],
        );
      }

      return Boolean(activeFilters[field.key]);
    },
    [activeFilters],
  );

  const availableFilterFields = React.useMemo(
    () => filterFields.filter((field) => !isFilterActive(field)),
    [filterFields, isFilterActive],
  );

  const selectedFilter = React.useMemo(
    () =>
      availableFilterFields.find((field) => field.key === selectedFilterKey),
    [availableFilterFields, selectedFilterKey],
  );

  React.useEffect(() => {
    if (selectedFilter || availableFilterFields.length === 0) return;

    setSelectedFilterKey(availableFilterFields[0].key);
    setFilterInputValue("");
    setFromDate("");
    setToDate("");
    setFromDateDisplay("");
    setToDateDisplay("");
  }, [availableFilterFields, selectedFilter]);

  const filterParams = React.useMemo(() => {
    const { __liveSearch, ...cleanFilters } = activeFilters as any;

    return cleanFilterParams({
      skip: pageIndex * pageSize,
      take: pageSize,
      status: statusFilter !== "All" ? statusFilter : undefined,
      recordTypeKey: menuFilter !== "All" ? menuFilter : undefined,
      orderBy: "createdAt:DESC",
      fetchParent: isSecretary,
      ...cleanFilters,
      // Inject live search into params — overrides nothing from chips
      ...(liveSearch ? { [liveSearch.key]: liveSearch.value } : {}),
    });
  }, [
    pageIndex,
    statusFilter,
    menuFilter,
    isSecretary,
    activeFilters,
    liveSearch,
  ]);

  React.useEffect(() => {
    if (!selectedFilter) return;
    if (selectedFilter.type === "dateRange") return;

    const value = filterInputValue.trim();

    if (value.length < 3) {
      setLiveSearch(null); // clear live search when input is too short
      return;
    }

    const handler = setTimeout(() => {
      // Write to separate liveSearch state, NOT the filter store
      setLiveSearch({ key: selectedFilter.key, value });
      setPageIndex(0);
    }, 500);

    return () => clearTimeout(handler);
  }, [filterInputValue, selectedFilter]);
  const activeFilterChips = React.useMemo<ActiveFilterChip[]>(
    () =>
      filterFields.reduce<ActiveFilterChip[]>((chips, field) => {
        if (field.type === "dateRange") {
          const from = activeFilters[field.fromKey];
          const to = activeFilters[field.toKey];
          if (!from && !to) return chips;

          chips.push({
            key: field.key,
            label: field.label,
            value: [
              from ? `${t("common.from", "From")}: ${from}` : "",
              to ? `${t("common.to", "To")}: ${to}` : "",
            ]
              .filter(Boolean)
              .join(" - "),
            remove: () =>
              activeFilterStore.removeFilters([field.fromKey, field.toKey]),
          });
          return chips;
        }

        const value = activeFilters[field.key];
        if (!value) return chips;

        chips.push({
          key: field.key,
          label: field.label,
          value: String(value),
          remove: () => activeFilterStore.removeFilter(field.key),
        });
        return chips;
      }, []),
    [activeFilterStore, activeFilters, filterFields, t],
  );

  const handleAddFilter = React.useCallback(() => {
    if (!selectedFilter) return;

    if (selectedFilter.type === "dateRange") {
      if (!fromDate && !toDate) return;
      activeFilterStore.setFilters({
        fromCreatedAt: fromDate,
        toCreatedAt: toDate,
      });
      setFromDate("");
      setToDate("");
      setFromDateDisplay("");
      setToDateDisplay("");
      setPageIndex(0);
      return;
    }

    const value = filterInputValue.trim();
    if (!value) return;

    activeFilterStore.setFilter(selectedFilter.key, value);
    setFilterInputValue("");
    setLiveSearch(null); // ← clear live search when promoting to chip
    setPageIndex(0);
  }, [activeFilterStore, filterInputValue, selectedFilter, fromDate, toDate]);

  const handleRemoveFilter = React.useCallback((remove: () => void) => {
    remove();
    setPageIndex(0);
  }, []);

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

  const {
    recordsResponse,
    isLoading,
    isError,
    refetch,
    recordParent,
    recordParentCount,
    refetchParent,
    isLoadingParent,
    isErrorParent,
  } = useUserRecords(filterParams);

  const unitId = userDetails?.employee?.[0]?.unitId ?? null;
  const { data } = useUnitConfiguration(unitId as string, {
    enabled: !!unitId,
  });
  const config = data?.data?.items?.[0];
  const waitForAllCollaboratorsBeforeAction =
    config?.waitAllCollaboratorsBeforeAction || false;

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

  const itemCount = isSelf
    ? (recordsResponse?.count ?? null)
    : (recordParentCount ?? null);

  const totalPages = itemCount ? Math.ceil(itemCount / pageSize) : 1;

  const statusOptions = React.useMemo(
    () => [
      { value: "All", label: t("userRecord.All") },
      { value: "Draft", label: t("userRecord.Draft") },
      { value: "Submitted", label: t("userRecord.Submitted") },
      { value: "Accepted", label: t("userRecord.Accepted") },
      { value: "Approved", label: t("userRecord.Approved") },
      { value: "Rejected", label: t("userRecord.Rejected") },
      { value: "Returned", label: t("userRecord.Returned") },
      { value: "Adjustment", label: t("userRecord.Adjustment") },
      { value: "Team Signature", label: t("userRecord.Team Signature") },
      { value: "Dispatched", label: t("userRecord.Sent") },
    ],
    [t],
  );

  const menu = React.useMemo(
    () => [
      { value: "All", label: t("userRecord.All") },
      { value: "external", label: t("nav.external") },
      { value: "internal", label: t("nav.internal") },
      { value: "internal_memo", label: t("nav.internal_memo") },
      { value: "direct", label: t("nav.direct", "Direct") },
    ],
    [t],
  );

  React.useEffect(() => {
    if (!itemCount) return;

    let newPage = pageIndex + 1;

    if (newPage > totalPages) {
      newPage = 1;
      setPageIndex(0);
    }

    setSearchParams((prev) => {
      const params = new URLSearchParams(prev);
      params.set("page", newPage.toString());
      return params;
    });
  }, [pageIndex, totalPages, itemCount, setSearchParams]);

  const handlePageChange = () => {
    const newPage = pageIndex + 1;
    setPageIndex(newPage);

    setSearchParams((prev) => {
      prev.set("page", newPage.toString());
      return prev;
    });
  };

  const refreshCurrentTable = React.useCallback(() => {
    if (isSelf) {
      refetch();
      return;
    }

    refetchParent?.();
  }, [isSelf, refetch, refetchParent]);

  const handleApproveClick = React.useCallback((row: RecordDto) => {
    setApproveTarget(row);
  }, []);

  const handleApproveClose = React.useCallback(() => {
    setApproveTarget(null);
    refreshCurrentTable();
    queryClient.invalidateQueries({ queryKey: ["userRecords"] });
    queryClient.invalidateQueries({ queryKey: ["recordParent"] });
    queryClient.invalidateQueries({ queryKey: ["dashbordReport"] });
  }, [queryClient, refreshCurrentTable]);

  const handleApproveSuccess = React.useCallback(() => {
    setApproveTarget(null);
    if (isSelf) {
      refreshCurrentTable();
    } else {
      navigate("/record-management/userRecords");
    }
  }, [isSelf, navigate, refreshCurrentTable]);

  const columns = React.useMemo(
    () =>
      UserRecordsColumns(
        isSelf ? refetch : refetchParent ? refetchParent : () => {},
        localizedName as (name?: { am?: string; en?: string }) => string,
        isSecretary,
        isSelf,
        waitForAllCollaboratorsBeforeAction,
        pageIndex + 1,
        { onApproveClick: handleApproveClick },
        openDropdownId,
        setOpenDropdownId,
      ),
    [
      isSelf,
      refetch,
      refetchParent,
      localizedName,
      isSecretary,
      waitForAllCollaboratorsBeforeAction,
      pageIndex,
      handleApproveClick,
      openDropdownId,
      setOpenDropdownId,
    ],
  );

  return isDelegated ? (
    <DelegationView />
  ) : (
    <div className="flex flex-col gap-2 bg-background text-foreground">
      {/* Header and Filter */}
      {/* <div className="flex justify-end">
        <Button
          size="sm"
          title={t("msg.recycleBin")}
          className="bg-gray-600 text-sm px-1 py-1 w-[40px] hover:bg-gray-700"
          onClick={() =>
            navigate("/record-management/userRecords/softDelete")
          }
        >
          <Trash2 className="h-4 w-4" />
        </Button>
      </div> */}

      <div className="flex items-start justify-between flex-wrap gap-4 mb-4">
        <h4 className="text-xl font-medium text-gray-900 dark:text-gray-100">
          {t("userRecord.Letters")}
        </h4>

        <div className="flex flex-col items-end gap-2 w-full sm:w-auto">
          <Button
            variant="addRecordBtn"
            onClick={() =>
              navigate("/record-management/userRecords/addUserRecord")
            }
          >
            <CirclePlus className="mr-3" />
            {t("userRecord.Add Record")}
          </Button>
          <div className="flex flex-col gap-2 w-full sm:w-auto">
            <div className="flex flex-col sm:flex-row items-start sm:items-center gap-2 w-full sm:w-auto">
              <Select
                value={selectedFilter?.key ?? ""}
                onValueChange={(val) => {
                  setSelectedFilterKey(val as FilterConfig["key"]);
                  setFilterInputValue("");
                  setLiveSearch(null); // ← add this
                  setFromDate("");
                  setToDate("");
                  setFromDateDisplay("");
                  setToDateDisplay("");
                }}
                disabled={availableFilterFields.length === 0}
              >
                <SelectTrigger className="w-full sm:w-[200px]">
                  <SelectValue placeholder={t("userRecord.Filter by")} />
                </SelectTrigger>
                <SelectContent>
                  {availableFilterFields.map((field) => (
                    <SelectItem key={field.key} value={field.key}>
                      {field.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>

              {selectedFilter?.type === "dateRange" ? (
                <div className="flex flex-col sm:flex-row gap-2">
                  {lang.startsWith("en") ? (
                    <>
                      <label className="mt-2">From: </label>
                      <Input
                        type="date"
                        value={fromDate}
                        onChange={(e) => setFromDate(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter") handleAddFilter();
                        }}
                        className="w-[150px]"
                      />
                      <label className="mt-2">To: </label>
                      <Input
                        type="date"
                        value={toDate}
                        onChange={(e) => setToDate(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter") handleAddFilter();
                        }}
                        min={fromDate}
                        className="w-[150px]"
                      />
                    </>
                  ) : (
                    <div className="flex flex-wrap items-center gap-3">
                      <div className="relative">
                        <label className="font-medium mr-2">ከ:</label>
                        <input
                          type="text"
                          value={fromDateDisplay}
                          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={fromDate}
                              onChange={(ethiopianDate: string) => {
                                const gregorianDate =
                                  convertEthiopianToGregorian(ethiopianDate);
                                const formatted = gregorianDate
                                  .toISOString()
                                  .split("T")[0];
                                setFromDate(formatted);
                                setFromDateDisplay(ethiopianDate);
                                setShowFromPicker(false);
                              }}
                            />
                          </div>
                        )}
                      </div>

                      <div className="relative">
                        <label className="font-medium mr-2">እስከ:</label>
                        <input
                          type="text"
                          value={toDateDisplay}
                          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={toDate}
                              onChange={(ethiopianDate: string) => {
                                const gregorianDate =
                                  convertEthiopianToGregorian(ethiopianDate);
                                const formatted = gregorianDate
                                  .toISOString()
                                  .split("T")[0];
                                setToDate(formatted);
                                setToDateDisplay(ethiopianDate);
                                setShowToPicker(false);
                              }}
                            />
                          </div>
                        )}
                      </div>
                    </div>
                  )}
                </div>
              ) : (
                <div className="relative w-full sm:w-[200px]">
                  <Input
                    type="text"
                    className="pl-8"
                    placeholder={`${t(
                      "userRecord.Search",
                    )} ${selectedFilter?.label.toLowerCase() ?? ""}`}
                    value={filterInputValue}
                    onChange={(e) => setFilterInputValue(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") {
                        const value = filterInputValue.trim();
                        if (value.length < 3) return;
                        if (selectedFilter)
                          activeFilterStore.setFilter(
                            selectedFilter.key,
                            value,
                          );
                        setFilterInputValue("");
                        setLiveSearch(null); // ← clear live search
                        setPageIndex(0);
                      }
                    }}
                    disabled={!selectedFilter}
                  />
                  <Search className="absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-500" />
                </div>
              )}

              <Button
                type="button"
                variant="outline"
                onClick={handleAddFilter}
                disabled={
                  !selectedFilter ||
                  (selectedFilter.type === "dateRange"
                    ? !fromDate && !toDate
                    : !filterInputValue.trim())
                }
              >
                {t("common.add", "Add Filter")}
              </Button>
            </div>

            {activeFilterChips.length > 0 && (
              <div className="flex flex-wrap items-center gap-2">
                {activeFilterChips.map((filter) => (
                  <Badge
                    key={filter.key}
                    variant="outline"
                    className="flex items-center gap-1 rounded-md px-2 py-1 text-sm"
                  >
                    <span className="font-medium">{filter.label}:</span>
                    <span>{filter.value}</span>
                    <button
                      type="button"
                      onClick={() => handleRemoveFilter(filter.remove)}
                      className="ml-1 rounded-sm p-0.5 hover:bg-gray-100 dark:hover:bg-gray-800"
                      aria-label={`${t("common.remove", "Remove")} ${
                        filter.label
                      }`}
                    >
                      <X className="h-3.5 w-3.5" />
                    </button>
                  </Badge>
                ))}
              </div>
            )}
          </div>
        </div>
      </div>

      <div className="flex flex-wrap gap-2 sm:gap-3 md:gap-4">
        {menu.map((item) => (
          <button
            key={item.value}
            onClick={() => setMenuFilter(item.value)}
            className={cn(
              "flex items-center justify-center gap-1 sm:gap-2 text-base base:text-base border min-w-[90px] sm:min-w-[120px] md:min-w-[180px] rounded-md px-2 py-1.5 relative transition-colors cursor-pointer",
              menuFilter === item.value
                ? "text-primary-700 dark:text-primary-foreground border-primary dark:border-primary bg-primary-50 dark:bg-primary/30"
                : "text-gray-600 dark:text-gray-300 border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700",
            )}
          >
            {item.label}
          </button>
        ))}
      </div>

      {secretaryList(isSecretary, secretaryView, setSecretaryView, "SEC")}

      <div className="flex flex-wrap gap-2 mb-4">
        {statusOptions.map((opt) => (
          <Button
            key={opt.value}
            variant={statusFilter === opt.value ? "linkActive" : "link"}
            onClick={() => {
              setStatusFilter(opt.value);
              setPageIndex(0);
            }}
            className="rounded-md text-base base:text-base"
          >
            {opt.label}
          </Button>
        ))}
      </div>

      {loading ? (
        <Loader />
      ) : Error ? (
        <div className="flex flex-col items-center justify-center h-full p-6 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
          <h2 className="text-xl font-semibold text-red-700 dark:text-red-400">
            {t("msg.error")}
          </h2>
        </div>
      ) : (
        <>
          <AdvancedTable
            columns={columns}
            data={isSelf ? recordsResponse?.items || [] : recordParent || []}
            tableName="User Records"
            toolBarPosition="right"
            hideToolbarFilter
            itemCount={
              isSelf ? recordsResponse?.count || 0 : recordParentCount || 0
            }
            pageIndex={pageIndex}
            onPageChange={setPageIndex}
            nextFunction={handlePageChange}
            prevFunction={() => setPageIndex(Math.max(0, pageIndex - 1))}
            refresh={isSelf ? refetch : refetchParent}
          />
          {approveTarget && (
            <ApproveRecord
              recordId={approveTarget.id}
              recordData={{
                unitId: approveTarget.unitId,
                recordTypeKey: approveTarget.recordTypeKey,
              }}
              preferredLanguage={approveTarget.preferredLanguage}
              onSuccess={handleApproveSuccess}
              onClose={handleApproveClose}
              open={true}
            />
          )}
        </>
      )}
    </div>
  );
};

export default UserRecords;
