import {
  Button,
  IconButton,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import axios from "axios";
import { useContext, useEffect, useState, useMemo, useCallback } from "react";
import moment from "moment";
import { DatePicker } from "@mui/x-date-pickers";
import { AppContext } from "../../../../contexts/AppContext";
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
import { format } from "date-fns-jalali";
import { Grid } from "../../../../components/grid/Grid";
import { SPACING } from "../../../../data/spacing";
import { AggregateUploadDoc } from "../aggregate-upload-doc/aggregate-upload-doc";
import ShowImage from "../../../../components/show-image/ShowImage";
import { useFormik } from "formik";
import { salughterAggregateQuantityService } from "../../services/salughter-aggregate-quantity";
import { useDispatch, useSelector } from "react-redux";
import {
  CLOSE_MODAL,
  LOADING_END,
  LOADING_START,
  OPEN_MODAL,
} from "../../../../lib/redux/slices/appSlice";
import { VetFarmEditTrafficCode } from "../../../vet-farm/components/vet-farm-edit-traffic-code/VetFarmEditTrafficCode";
import { RiFileExcel2Fill } from "react-icons/ri";
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
import { slaughterEnterLoadInformationGetDashboard } from "../../services/slaughter-enter-load-information-get-dashboard";
import { RiSearchLine } from "react-icons/ri";
import EditIcon from "@mui/icons-material/Edit";
import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";
import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range";
import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight";
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";

// Constants
const ROLES = {
  PROVINCE_OPERATOR: "ProvinceOperator",
  SUPER_ADMIN: "SuperAdmin",
  ADMIN_X: "AdminX",
  SUPPORTER: "Supporter",
  VET_SUPERVISOR: "VetSupervisor",
  VET_FARM: "VetFarm",
  CITY_VET: "CityVet",
};

const KILL_TYPES = {
  FREEZING: "انجماد",
  EXPORT: "صادرات",
  NORMAL: "عادی",
};

const DEFAULT_PER_PAGE = 10;
const DEFAULT_PAGE = 1;

// Helper functions
const formatDate = (date) => {
  if (!date) return "-";
  return format(new Date(date), "yyyy/MM/dd");
};

const formatCurrency = (value) => {
  return value ? `${value.toLocaleString()} ﷼` : "-";
};

const formatNumber = (value) => {
  return value ? value.toLocaleString() : "-";
};

const formatUserInfo = (name, mobile) => {
  return name && mobile ? `${name} (${mobile})` : "-";
};

const getKillType = (item) => {
  if (item?.poultryRequest?.freezing) return KILL_TYPES.FREEZING;
  if (item?.poultryRequest?.export) return KILL_TYPES.EXPORT;
  return KILL_TYPES.NORMAL;
};

const buildApiUrl = (params) => {
  const { textValue, role, date1, date2, page, perPage, roleKey } = params;
  const baseUrl = "kill_house_request_aggregate_load/";
  const queryParams = new URLSearchParams({
    check: "",
    search: "filter",
    value: textValue || "",
    role: role || "",
    date1: date1 || "",
    date2: date2 || "",
    page: page || DEFAULT_PAGE,
    page_size: perPage || DEFAULT_PER_PAGE,
  });

  if (roleKey) {
    queryParams.append("role_key", roleKey);
  }

  return `${baseUrl}?${queryParams.toString()}`;
};

const buildExcelUrl = (params) => {
  const { baseURL, date1, date2, role, roleKey, userKey, textValue } = params;
  const queryParams = new URLSearchParams({
    start: date1 || "",
    end: date2 || "",
    role: role || "",
    state: "bar_pending",
    key: userKey || "",
    search: "filter",
    value: textValue || "",
  });

  if (roleKey) {
    queryParams.append("role_key", roleKey);
  }

  return `${baseURL}bar_excel/?${queryParams.toString()}`;
};

const isTrafficCodeEditable = (role, item) => {
  const adminRoles = [
    ROLES.PROVINCE_OPERATOR,
    ROLES.SUPER_ADMIN,
    ROLES.ADMIN_X,
    ROLES.SUPPORTER,
    ROLES.VET_SUPERVISOR,
  ];

  if (adminRoles.includes(role)) {
    return true;
  }

  const vetRoles = [ROLES.VET_FARM, ROLES.CITY_VET];
  return (
    item.trash !== true &&
    item.assignmentStateArchive === "pending" &&
    !item?.clearanceCode &&
    vetRoles.includes(role)
  );
};

export const EnterAggregateLoadInformation = () => {
  const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
    useContext(AppContext);

  // Redux
  const userKey = useSelector((state) => state.userSlice.userProfile.key);
  const selectedSubUser = useSelector(
    (state) => state.userSlice.selectedSubUser
  );
  const dispatch = useDispatch();

  // State
  const [data, setData] = useState([]);
  const [totalRows, setTotalRows] = useState(0);
  const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE);
  const [textValue, setTextValue] = useState("");
  const [page, setPage] = useState(DEFAULT_PAGE);
  const [tableData, setTableData] = useState([]);
  const [dashboardData, setDashboardData] = useState([]);

  // Memoized values
  const currentRole = useMemo(() => getRoleFromUrl(), []);
  const roleKey = useMemo(
    () => (checkPathStartsWith("slaughter") ? selectedSubUser?.key || "" : ""),
    [selectedSubUser?.key]
  );

  // Initialize dates
  useEffect(() => {
    const currentDate = moment(new Date()).format("YYYY-MM-DD");
    setSelectedDate1(currentDate);
    setSelectedDate2(currentDate);
  }, [setSelectedDate1, setSelectedDate2]);

  // Fetch API data
  const fetchApiData = useCallback(
    async (pageNumber = page) => {
      dispatch(LOADING_START());
      try {
        const url = buildApiUrl({
          textValue,
          role: currentRole,
          date1: selectedDate1,
          date2: selectedDate2,
          page: pageNumber,
          perPage,
          roleKey,
        });

        const response = await axios.get(url);
        setData(response.data.results);
        setTotalRows(response.data.count);
      } catch (error) {
        console.error("Error fetching data:", error);
      } finally {
        dispatch(LOADING_END());
      }
    },
    [
      textValue,
      currentRole,
      selectedDate1,
      selectedDate2,
      perPage,
      roleKey,
      page,
      dispatch,
    ]
  );

  // Fetch dashboard data
  const fetchDashboardData = useCallback(() => {
    dispatch(
      slaughterEnterLoadInformationGetDashboard({
        selectedDate1,
        selectedDate2,
        text: textValue,
        role_key: roleKey,
      })
    ).then((r) => {
      setDashboardData(r.payload.data);
    });
  }, [selectedDate1, selectedDate2, textValue, roleKey, dispatch]);

  // Handlers
  const handlePageChange = (newPage) => {
    fetchApiData(newPage);
    setPage(newPage);
  };

  const handlePerRowsChange = (newPerRows) => {
    setPerPage(newPerRows);
    setPage(DEFAULT_PAGE);
  };

  const handleSubmit = async (event) => {
    event.preventDefault();
    await fetchApiData(DEFAULT_PAGE);
    fetchDashboardData();
    setPage(DEFAULT_PAGE);
  };

  const handleTextChange = (event) => {
    setTextValue(event.target.value);
  };

  const handleDateChange1 = (date) => {
    if (date) {
      setSelectedDate1(moment(date).format("YYYY-MM-DD"));
    }
  };

  const handleDateChange2 = (date) => {
    if (date) {
      setSelectedDate2(moment(date).format("YYYY-MM-DD"));
    }
  };

  const handleOpenModal = useCallback(
    (item) => {
      dispatch(
        OPEN_MODAL({
          title: "ثبت اطلاعات بار",
          content: <Operation item={item} fetchApiData={fetchApiData} />,
        })
      );
    },
    [dispatch, fetchApiData]
  );

  // Initial data fetch
  useEffect(() => {
    fetchApiData(DEFAULT_PAGE);
    fetchDashboardData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Refetch when filters change
  useEffect(() => {
    fetchApiData(DEFAULT_PAGE);
    fetchDashboardData();
    setPage(DEFAULT_PAGE);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedDate1, selectedDate2, perPage, roleKey]);

  // Transform data to table format
  useEffect(() => {
    const transformedData = data?.map((item, i) => {
      const rowNumber =
        page === DEFAULT_PAGE ? i + 1 : i + perPage * (page - 1) + 1;
      const hasAssignmentInfo = !!item?.assignmentInfo?.realQuantity;

      return [
        rowNumber,
        hasAssignmentInfo ? (
          <Grid container direction="column" key={item.key}>
            <Grid>{formatNumber(item?.assignmentInfo?.realQuantity)} قطعه</Grid>
            <Grid>{formatNumber(item?.assignmentInfo?.netWeight)} کیلوگرم</Grid>
            <Tooltip title="ویرایش اطلاعات بار" placement="top">
              <IconButton
                color="primary"
                onClick={() => handleOpenModal(item)}
                size="small"
              >
                <EditIcon fontSize="small" />
              </IconButton>
            </Tooltip>
          </Grid>
        ) : (
          <Tooltip key={item.key} title="ثبت اطلاعات بار" placement="top">
            <IconButton
              color="primary"
              onClick={() => handleOpenModal(item)}
              size="small"
            >
              <AddCircleOutlineIcon fontSize="small" />
            </IconButton>
          </Tooltip>
        ),
        item?.assingmentInformation?.carWeightWithLoadImage ? (
          <Grid key={item.key}>
            <ShowImage
              src={item?.assingmentInformation?.carWeightWithLoadImage}
            />
            <AggregateUploadDoc
              isSingular
              item={item}
              updateTable={fetchApiData}
            />
          </Grid>
        ) : (
          <AggregateUploadDoc
            key={item.key}
            isSingular
            item={item}
            updateTable={fetchApiData}
          />
        ),
        <ShowImage
          key={`empty-${i}`}
          src={item?.assignmentInfo?.imageWithoutBar}
        />,
        <ShowImage
          key={`full-${i}`}
          src={item?.assignmentInfo?.imageWithBar}
        />,
        <Typography
          key={`barcode-${i}`}
          style={{ fontSize: "13px", color: item?.trash ? "red" : "black" }}
        >
          {item.barCode}
        </Typography>,
        <VetFarmEditTrafficCode
          key={`traffic-${i}`}
          updateTable={fetchApiData}
          killHouseRequestKey={item.key}
          trafficCode={item?.trafficCode}
          isEditable={isTrafficCodeEditable(currentRole, item)}
        />,
        formatCurrency(item?.amount),
        formatDate(item?.poultryRequest?.sendDate),
        formatUserInfo(
          item.killhouseUser?.name,
          item.killhouseUser?.killHouseOperator?.user?.mobile
        ),
        item?.killer
          ? formatUserInfo(
              item.killer?.name,
              item.killer?.killHouseOperator?.user?.mobile
            )
          : "-",
        formatUserInfo(
          item.poultryRequest?.poultry?.unitName,
          item.poultryRequest?.poultry?.user?.mobile
        ),
        item?.poultryRequest?.age || "-",
        formatNumber(item.quantity),
        formatNumber(item?.weightInfo?.weight),
        formatCurrency(item?.poultryRequest?.amount),
        formatCurrency(item?.weightInfo?.killHousePrice),
        `${item.addCar?.driver?.typeCar || ""} ${
          item.addCar?.driver?.pelak || ""
        }`.trim() || "-",
        formatUserInfo(
          item.addCar?.driver?.driverName,
          item.addCar?.driver?.driverMobile
        ),
        formatNumber(item.vetAcceptedRealQuantity),
        formatNumber(item.vetAcceptedRealWeight),
        item?.poultryRequest?.orderCode || "-",
        item?.finalBarState || "-",
        getKillType(item),
      ];
    });

    setTableData(transformedData || []);
  }, [data, page, perPage, currentRole, handleOpenModal, fetchApiData]);

  // Table columns
  const dashboardColumns = [
    "تعداد بار",
    "مجموع تعداد اولیه",
    "مجموع وزن اولیه (کیلوگرم)",
    "مجموع تعداد تحویلی دامپزشک",
    "مجموع وزن تحویلی دامپزشک (کیلوگرم)",
  ];

  const tableColumns = [
    "ردیف",
    "تعداد/وزن خالص",
    "سند",
    "بارنامه خالی",
    "بارنامه پر",
    "کدبار",
    "کد بهداشتی حمل و نقل",
    "قیمت مرغ زنده‌ی بار",
    "تاریخ کشتار",
    "خریدار",
    "کشتارکن اختصاصی",
    "مرغدار",
    "سن مرغ",
    "تعداد اولیه",
    "وزن اولیه بار (کیلوگرم)",
    "قیمت مرغدار",
    "قیمت کشتارگاه",
    "ماشین",
    "راننده",
    "تحویلی دامپزشک (قطعه)",
    "وزن تحویلی دامپزشک (کیلوگرم)",
    "کدسفارش کشتار",
    "وضعیت بار",
    "نوع کشتار",
  ];

  const dashboardRow = [
    formatNumber(dashboardData?.lenKillHouseRequest),
    formatNumber(dashboardData?.firstQuantity),
    formatNumber(dashboardData?.firstWeight),
    formatNumber(dashboardData?.vetAcceptedRealQuantity),
    formatNumber(dashboardData?.vetAcceptedRealWeight),
  ];

  const excelUrl = buildExcelUrl({
    baseURL: axios.defaults.baseURL,
    date1: selectedDate1,
    date2: selectedDate2,
    role: currentRole,
    roleKey,
    userKey,
    textValue,
  });

  return (
    <Grid container justifyContent="center">
      <Grid
        container
        alignItems="start"
        justifyContent="space-between"
        gap={2}
        paddingTop={2}
        mb={1}
      >
        <Grid container alignItems="center" gap={SPACING.SMALL}>
          <Grid>
            <DatePicker
              label="از تاریخ"
              renderInput={(params) => (
                <TextField
                  size="small"
                  style={{ width: "160px" }}
                  {...params}
                />
              )}
              value={selectedDate1}
              onChange={handleDateChange1}
            />
          </Grid>
          <Grid>
            <DatePicker
              label="تا تاریخ"
              renderInput={(params) => (
                <TextField
                  size="small"
                  style={{ width: "160px" }}
                  {...params}
                />
              )}
              value={selectedDate2}
              onChange={handleDateChange2}
            />
          </Grid>
          <form onSubmit={handleSubmit}>
            <TextField
              size="small"
              autoComplete="off"
              label="جستجو"
              variant="outlined"
              style={{ width: 250 }}
              onChange={handleTextChange}
              value={textValue}
            />
            <Button type="submit" endIcon={<RiSearchLine />}>
              جستجو
            </Button>
          </form>
          {!!data?.length && (
            <Grid>
              <Tooltip title="خروجی اکسل">
                <a href={excelUrl} rel="noreferrer">
                  <Button color="success">
                    <RiFileExcel2Fill size={32} />
                  </Button>
                </a>
              </Tooltip>
            </Grid>
          )}
        </Grid>
      </Grid>
      <Grid container mt={2} mb={4} isDashboard xs={12}>
        <ResponsiveTable
          noPagination
          isDashboard
          columns={dashboardColumns}
          data={[dashboardRow]}
          title="خلاصه اطلاعات"
        />
      </Grid>

      <ResponsiveTable
        data={tableData}
        columns={tableColumns}
        handlePageChange={handlePageChange}
        totalRows={totalRows}
        page={page}
        perPage={perPage}
        handlePerRowsChange={handlePerRowsChange}
        title="وارد کردن اطلاعات بار"
      />
    </Grid>
  );
};

const Operation = ({ item, fetchApiData }) => {
  const [openNotif] = useContext(AppContext);
  const { weightRange } = useSelector((state) => state.provinceSlice);
  const dispatch = useDispatch();
  const selectedSubUser = useSelector(
    (state) => state.userSlice.selectedSubUser
  );
  const currentRole = useMemo(() => getRoleFromUrl(), []);

  // Fetch weight range on mount
  useEffect(() => {
    dispatch(
      provincePolicyGetWeightRange({
        role_key: checkPathStartsWith("slaughter")
          ? selectedSubUser?.key || ""
          : "",
      })
    );
  }, [selectedSubUser?.key]);

  // Validation helpers
  const validateNumeric = (value) => /^\d+$/.test(value);

  const checkVolumeLimits = (quantity) => {
    const { maximumLoadVolumeReduction, maximumLoadVolumeIncrease } =
      item?.killhouseUser || {};
    const acceptedQuantity = item?.acceptedRealQuantity || 0;

    if (
      maximumLoadVolumeReduction !== 0 &&
      quantity < acceptedQuantity * (1 - maximumLoadVolumeReduction / 100)
    ) {
      return {
        isValid: false,
        message:
          "حجم وارد شده با مجوز حداکثر افزایش/کاهش ورود اطلاعات بار مطابقت ندارد!",
      };
    }

    if (
      maximumLoadVolumeIncrease !== 0 &&
      quantity > acceptedQuantity * (1 + maximumLoadVolumeIncrease / 100)
    ) {
      return {
        isValid: false,
        message:
          "حجم وارد شده با مجوز حداکثر افزایش/کاهش ورود اطلاعات بار مطابقت ندارد!",
      };
    }

    return { isValid: true };
  };

  const checkWeightValidation = (weight, quantity) => {
    const adminRoles = [ROLES.SUPER_ADMIN, ROLES.ADMIN_X];
    if (adminRoles.includes(currentRole)) {
      return { isValid: true };
    }

    const averageWeight = parseInt(weight) / parseInt(quantity);
    if (
      !isValidIndexWeight(weightRange, item?.poultryRequest?.age, averageWeight)
    ) {
      return {
        isValid: false,
        message:
          "میانگین وزنی با احراز سنی مطابقت ندارد. لطفا با اتحادیه تماس بگیرید.",
      };
    }

    return { isValid: true };
  };

  const formik = useFormik({
    initialValues: {
      quantity: "",
      weight: "",
    },
    onSubmit: async (values) => {
      // Validate volume limits
      const volumeCheck = checkVolumeLimits(parseInt(values.quantity));
      if (!volumeCheck.isValid) {
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: volumeCheck.message,
          severity: "error",
        });
        return;
      }

      // Validate weight
      const weightCheck = checkWeightValidation(values.weight, values.quantity);
      if (!weightCheck.isValid) {
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: weightCheck.message,
          severity: "error",
        });
        return;
      }

      // Submit data
      const result = await dispatch(
        salughterAggregateQuantityService({
          kill_house_request_key: item.key,
          role: currentRole,
          net_weight: values.weight,
          exploited_carcass: 0,
          real_quantity: values.quantity,
        })
      );

      if (result.payload.error) {
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: result.payload.error,
          severity: "error",
        });
      } else {
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: "عملیات با موفقیت انجام شد.",
          severity: "success",
        });
        dispatch(CLOSE_MODAL());
        fetchApiData(DEFAULT_PAGE);
      }
    },
    validate: (values) => {
      const errors = {};
      if (!validateNumeric(values.weight)) {
        errors.weight = "لطفا عدد وارد کنید";
      }
      if (!validateNumeric(values.quantity)) {
        errors.quantity = "لطفا عدد وارد کنید";
      }
      return errors;
    },
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <Grid
        container
        gap={SPACING.SMALL}
        alignItems="center"
        justifyContent="center"
      >
        <TextField
          label="وزن خالص (کیلوگرم)"
          variant="outlined"
          fullWidth
          type="text"
          name="weight"
          id="weight"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.weight}
          error={formik.touched.weight && Boolean(formik.errors.weight)}
          helperText={formik.touched.weight && formik.errors.weight}
        />
        <TextField
          label="تعداد واقعی (قطعه)"
          variant="outlined"
          fullWidth
          type="text"
          name="quantity"
          id="quantity"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.quantity}
          error={formik.touched.quantity && Boolean(formik.errors.quantity)}
          helperText={formik.touched.quantity && formik.errors.quantity}
        />

        <Button type="submit" fullWidth variant="contained">
          ثبت
        </Button>
      </Grid>
    </form>
  );
};
