import { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import DatePicker from "../date-picker/DatePicker";
import { Grid } from "../Grid/Grid";
import Textfield from "../Textfeild/Textfeild";
import Typography from "../Typography/Typography";
import {
  CircleStackIcon,
  DocumentArrowDownIcon,
} from "@heroicons/react/24/outline";
import { checkIsMobile } from "../../utils/checkIsMobile";
import AutoComplete from "../AutoComplete/AutoComplete";
import { Tooltip } from "../Tooltip/Tooltip";
import api from "../../utils/axios";
import { useBackdropStore } from "../../context/zustand-store/appStore";
import { useToast } from "../../hooks/useToast";
import { useApiRequest } from "../../utils/useApiRequest";
import { getNestedValue } from "../../utils/getNestedValue";
import { getFaPermissions } from "../../utils/getFaPermissions";

interface FilterItem {
  key: number | string;
  value: string;
  disabled?: boolean;
}

interface FilterConfig {
  key?: string;
  data?: FilterItem[];
  api?: string;
  selectedKeys: (number | string)[];
  onChange: (keys: (number | string)[]) => void;
  title: string;
  size?: "small" | "medium" | "large";
  inPage?: boolean;
  selectField?: boolean;
  keyField?: string;
  valueField?: string | string[];
  valueField2?: string | string[];
  valueField3?: string | string[];
  filterAddress?: string[];
  filterValue?: string[];
  valueTemplate?: string;
  valueTemplateProps?: Array<{ [key: string]: "string" | "number" }>;
  groupBy?: string | string[];
  groupFunction?: (item: any) => string;
}

type ExcelProps = {
  title?: string;
  link?: string;
};

interface PaginationParametersProps {
  noCustomDate?: boolean;
  defaultActive?: boolean;
  justOne?: boolean;
  noSearch?: boolean;
  startLabel?: string;
  endLabel?: string;
  title?: string;
  onChange?: (data: {
    date1?: string | null;
    date2?: string | null;
    search?: string | null;
    [key: string]: any;
  }) => void;
  getData?: () => void;
  children?: React.ReactNode;
  filters?: FilterConfig[];
  excelInfo?: ExcelProps;
}

const ApiBasedFilter: React.FC<{
  filter: FilterConfig;
}> = ({ filter }) => {
  const [filterData, setFilterData] = useState<FilterItem[]>([]);

  if (!filter.api) {
    return null;
  }

  const formatValue = (value: any, fieldKey: string) => {
    if (!filter.valueTemplate || !filter.valueTemplateProps) return value;

    const templateProp = filter.valueTemplateProps.find(
      (prop) => prop[fieldKey]
    );
    if (!templateProp) return value;

    const fieldType = templateProp[fieldKey];

    if (fieldType === "number") {
      const numValue = typeof value === "number" ? value : Number(value);
      return !isNaN(numValue) ? numValue.toLocaleString() : String(value);
    } else if (fieldType === "string") {
      let result = String(value);
      if (typeof value === "string" && value.includes(",")) {
        result = value.replace(/,/g, "");
      }
      return result;
    }

    return value;
  };

  const { data: apiData } = useApiRequest({
    api: filter.api,
    params: { page: 1, page_size: 1000 },
    queryKey: [filter.api, filter.key],
    disableBackdrop: true,
  });

  useEffect(() => {
    if (apiData?.results && filter.api) {
      let data;

      if (filter.filterAddress && filter.filterValue) {
        data = apiData.results?.filter(
          (item: any) =>
            !filter.filterValue!.includes(
              getNestedValue(item, filter.filterAddress!)
            )
        );
      } else {
        data = apiData.results;
      }

      const keyField = filter.keyField || "id";
      const valueField = filter.valueField || "name";

      const formattedData = data?.map((option: any) => ({
        key: option[keyField],
        value: filter.valueTemplate
          ? filter.valueTemplate
              .replace(
                /v1/g,
                formatValue(
                  valueField === "page"
                    ? getFaPermissions(option[valueField])
                    : typeof valueField === "string"
                    ? option[valueField]
                    : getNestedValue(option, valueField),
                  "v1"
                )
              )
              .replace(
                /v2/g,
                formatValue(
                  filter.valueField2
                    ? typeof filter.valueField2 === "string"
                      ? option[filter.valueField2]
                      : getNestedValue(option, filter.valueField2)
                    : "",
                  "v2"
                )
              )
              .replace(
                /v3/g,
                formatValue(
                  filter.valueField3
                    ? typeof filter.valueField3 === "string"
                      ? option[filter.valueField3]
                      : getNestedValue(option, filter.valueField3)
                    : "",
                  "v3"
                )
              )
          : `${
              valueField === "page"
                ? getFaPermissions(option[valueField])
                : typeof valueField === "string"
                ? option[valueField]
                : getNestedValue(option, valueField)
            }  ${
              filter.valueField2
                ? " - " +
                  (typeof filter.valueField2 === "string"
                    ? option[filter.valueField2]
                    : getNestedValue(option, filter.valueField2))
                : ""
            }  ${
              filter.valueField3
                ? "(" +
                  (typeof filter.valueField3 === "string"
                    ? option[filter.valueField3]
                    : getNestedValue(option, filter.valueField3)) +
                  ")"
                : ""
            }`,
      }));

      setFilterData(formattedData || []);
    }
  }, [apiData, filter]);

  return (
    <AutoComplete
      key={filter.key}
      inPage={filter.inPage ?? true}
      size={filter.size ?? "small"}
      data={filterData}
      selectedKeys={filter.selectedKeys}
      onChange={filter.onChange}
      title={filter.title}
      selectField={filter.selectField}
    />
  );
};

export const PaginationParameters: React.FC<PaginationParametersProps> = ({
  noCustomDate = false,
  defaultActive = false,
  justOne = false,
  noSearch = false,
  startLabel = "",
  endLabel = "تا",
  title,
  onChange,
  getData,
  children,
  filters = [],
  excelInfo,
}) => {
  const [selectedDate1, setSelectedDate1] = useState<string>();
  const [selectedDate2, setSelectedDate2] = useState<string>();
  const [keyword, setKeyword] = useState<string>("");
  const [enableDates, setEnableDates] = useState<boolean>(defaultActive);
  const { openBackdrop, closeBackdrop } = useBackdropStore();
  const showToast = useToast();
  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const data = {
      start: enableDates ? selectedDate1 : null,
      end: enableDates ? selectedDate2 : null,
      search: noSearch ? null : keyword,
    };
    await onChange?.(data);
    getData?.();
  };

  const handleExcelDownload = () => {
    openBackdrop();
    if (!excelInfo?.link) return;

    const urlParts = excelInfo.link.split("?");
    const baseUrl = urlParts[0];
    const existingParams: Record<string, string> = {};

    if (urlParts[1]) {
      const queryString = urlParts[1];
      const params = new URLSearchParams(queryString);
      params.forEach((value, key) => {
        if (value) {
          existingParams[key] = value;
        }
      });
    }

    const mergedParams: Record<string, string | undefined> = {
      ...existingParams,
      ...(keyword ? { search: keyword } : {}),
      ...(enableDates && selectedDate1 && selectedDate2
        ? { start: selectedDate1, end: selectedDate2 }
        : enableDates && selectedDate1
        ? { start: selectedDate1 }
        : enableDates && selectedDate2
        ? { end: selectedDate2 }
        : {}),
    };

    const finalParams: Record<string, string> = {};
    Object.keys(mergedParams).forEach((key) => {
      const value = mergedParams[key];
      if (value !== undefined && value !== null && value !== "") {
        finalParams[key] = value;
      }
    });

    api
      .get(baseUrl, {
        params: finalParams,
        responseType: "blob",
      })
      .then((response) => {
        const url = window.URL.createObjectURL(new Blob([response.data]));

        const link = document.createElement("a");
        link.href = url;
        link.setAttribute(
          "download",
          `${excelInfo?.title || title || "خروجی"}.xlsx`
        );

        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        window.URL.revokeObjectURL(url);
      })
      .catch((error) => {
        console.error("Error downloading file:", error);
        showToast("در حال حاضر امکان دانلود خروجی اکسل وجود ندارد", "error");
      })
      .finally(() => {
        closeBackdrop();
      });
  };

  const renderDate1 = (
    <DatePicker
      size="small"
      disabled={!noCustomDate && !enableDates}
      value={selectedDate1}
      onChange={(r) => setSelectedDate1(r)}
      label={startLabel}
    />
  );

  const renderDate2 = !justOne ? (
    <DatePicker
      size="small"
      disabled={!noCustomDate && !enableDates}
      value={selectedDate2}
      onChange={(r) => setSelectedDate2(r)}
      label={endLabel}
    />
  ) : (
    ""
  );

  const isMobile = checkIsMobile();

  if (isMobile) {
    return (
      <form onSubmit={handleSubmit}>
        <div className="flex flex-col bg-gray-100 dark:bg-dark-800 rounded-4xl m-4">
          <div className="flex-1 px-4 pt-6 pb-2 space-y-4">
            {(title || excelInfo) && (
              <div className="flex items-center gap-2">
                <CircleStackIcon className="h-6 w-6 text-primary-600 dark:text-white" />
                <Typography className="text-lg font-semibold text-gray-800 dark:text-white">
                  {title}
                </Typography>
                {excelInfo && (
                  <div
                    className="cursor-pointer rounded-sm px-1 border-red-400 shadow-b-xl shadow-sky-50"
                    onClick={handleExcelDownload}
                  >
                    <Tooltip
                      position="top"
                      title={
                        checkIsMobile() ? "" : excelInfo?.title || "خروجی اکسل"
                      }
                    >
                      <DocumentArrowDownIcon className="text-primary-600 w-5 animate-pulse" />
                    </Tooltip>
                  </div>
                )}
              </div>
            )}

            {!noCustomDate && (
              <div className="bg-white dark:bg-dark-600 shadow rounded-2xl p-4 flex items-center justify-between">
                <span className="text-sm text-gray-700 dark:text-gray-200">
                  فعال‌سازی بازه تاریخی
                </span>
                <button
                  type="button"
                  onClick={() => setEnableDates((prev) => !prev)}
                  className={`relative w-12 h-7 rounded-full transition-colors duration-300 ${
                    enableDates ? "bg-green-500" : "bg-gray-300"
                  }`}
                >
                  <motion.div
                    layout
                    transition={{ type: "spring", stiffness: 500, damping: 30 }}
                    className="absolute top-0.5 left-0.5 w-6 h-6 bg-white rounded-full shadow"
                    animate={{ x: enableDates ? 20 : 0 }}
                  />
                </button>
              </div>
            )}

            <div className="bg-white dark:bg-dark-600 shadow rounded-2xl p-4 space-y-2">
              {renderDate1}
              {renderDate2}
            </div>

            {filters.length > 0 && (
              <div className="bg-white dark:bg-dark-600 shadow rounded-2xl p-4 space-y-2">
                {filters.map((filter) =>
                  filter.api ? (
                    <ApiBasedFilter key={filter.key} filter={filter} />
                  ) : (
                    <AutoComplete
                      key={filter.key}
                      inPage={filter.inPage ?? true}
                      size={filter.size ?? "small"}
                      data={filter.data || []}
                      selectedKeys={filter.selectedKeys}
                      onChange={filter.onChange}
                      title={filter.title}
                      selectField={filter.selectField}
                    />
                  )
                )}
              </div>
            )}

            <div className="bg-white dark:bg-dark-600 shadow rounded-2xl p-4">
              {!noSearch && (
                <Textfield
                  inputSize="small"
                  fullWidth
                  placeholder="عبارت جستجو را وارد کنید"
                  value={keyword}
                  onChange={(e) => setKeyword(e.target.value)}
                />
              )}
              <motion.button
                whileHover={{ scale: 1.03 }}
                whileTap={{ scale: 0.97 }}
                type="submit"
                className="w-full mt-2 bg-primary-600 hover:bg-primary-700 text-white text-base font-semibold py-3 rounded-2xl shadow-lg transition-all"
              >
                جستجو
              </motion.button>
            </div>
          </div>
        </div>
      </form>
    );
  }

  return (
    <form onSubmit={handleSubmit}>
      <Grid className="flex flex-wrap gap-2 justify-center items-center p-4 w-full bg-gradient-to-r from-transparent to-transparent dark:via-gray-900 via-gray-100">
        {title && (
          <Grid className="bg-primary-100 items-center dark:bg-dark-700 ml-2 p-1 px-4 rounded-xl flex justify-center gap-2 w-full md:w-auto">
            <Grid>
              <CircleStackIcon className="h-6 w-6 text-primary-800 dark:text-white" />
            </Grid>
            <Grid>
              <Typography
                variant="body2"
                color="text-gray-600 dark:text-gray-100"
              >
                {title}
              </Typography>
            </Grid>
          </Grid>
        )}

        <div className="flex items-center gap-2">
          {filters.map((filter) => (
            <Grid
              container
              className="items-center gap-2 max-w-40"
              key={filter.key}
            >
              {filter.api ? (
                <ApiBasedFilter filter={filter} />
              ) : (
                <AutoComplete
                  inPage={filter.inPage ?? true}
                  size={filter.size ?? "small"}
                  data={filter.data || []}
                  selectedKeys={filter.selectedKeys}
                  onChange={filter.onChange}
                  title={filter.title}
                  selectField={filter.selectField}
                />
              )}
            </Grid>
          ))}
          {children}
        </div>

        {!noCustomDate && (
          <div className="flex items-center gap-2">
            <button
              type="button"
              onClick={() => setEnableDates((prev) => !prev)}
              className={`relative w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer ${
                enableDates ? "bg-green-500" : "bg-gray-300"
              }`}
            >
              <motion.div
                layout
                transition={{ type: "spring", stiffness: 500, damping: 30 }}
                className="absolute top-[2px] left-[2px] w-4 h-4 bg-white rounded-full shadow-md"
                animate={{ x: enableDates ? 20 : 0 }}
              />
            </button>
          </div>
        )}

        <AnimatePresence>
          <>
            <motion.div
              key="date1"
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 10 }}
              transition={{ duration: 0.3 }}
              className="w-full sm:w-auto flex-grow sm:flex-grow-0 min-w-[150px]"
            >
              {renderDate1}
            </motion.div>

            <motion.div
              key="date2"
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: 10 }}
              transition={{ duration: 0.3 }}
              className="w-full sm:w-auto flex-grow sm:flex-grow-0"
            >
              {renderDate2}
            </motion.div>
          </>
        </AnimatePresence>

        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ duration: 1 }}
          className="w-full sm:w-auto flex-grow sm:flex-grow-0"
        >
          {!noSearch && (
            <Textfield
              inputSize="small"
              fullWidth
              placeholder="جستجو"
              value={keyword}
              onChange={(e) => setKeyword(e.target.value)}
            />
          )}
        </motion.div>

        <motion.button
          whileHover={{ scale: 1.05 }}
          whileTap={{ scale: 0.95 }}
          type="submit"
          className="
          bg-primary-600 text-white rounded-xl px-6 py-1.5 text-sm font-medium shadow cursor-pointer
          hover:bg-primary-700 transition-colors
          w-full sm:w-auto min-w-[100px]
        "
        >
          جستجو
        </motion.button>

        {excelInfo && (
          <div
            className="cursor-pointer rounded-sm border-red-400 flex items-center justify-center"
            onClick={handleExcelDownload}
          >
            <Tooltip
              position="top"
              title={checkIsMobile() ? "" : excelInfo?.title || "خروجی اکسل"}
            >
              <DocumentArrowDownIcon className="text-primary-600 w-8 animate-pulse" />
            </Tooltip>
          </div>
        )}
      </Grid>
    </form>
  );
};
