import { useEffect, useState, useCallback } from "react";
import {
  Box,
  Grid,
  Card,
  CardContent,
  IconButton,
  Typography,
  Divider,
  Stack,
  InputAdornment,
  TextField,
} from "@mui/material";
import DoneIcon from "@mui/icons-material/Done";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import { DatePicker } from "@mui/x-date-pickers";
import { useFormik } from "formik";
import { Yup } from "../../../../lib/yup/yup";
import moment from "moment";
import { useDispatch, useSelector } from "react-redux";

import { freeBuyingPayment } from "../../services/free-buying-payment";
import { adminSettlementDirectBuying } from "../../services/admin-settlement-direct-buying-payment";
import { freeBuyDeletePaymentService } from "../../services/free-buying-delete-payment";
import { fixBase64 } from "../../../../utils/toBase64";
import { resizeImage } from "../../../../utils/resizeImage";
import { formatJustDate } from "../../../../utils/formatTime";

import { ImageUpload } from "../../../../components/image-upload/ImageUpload";
import ShowImage from "../../../../components/show-image/ShowImage";
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";

export const ProvinceSettlementSubmitDocument = ({
  modal_key,
  updateTable_modal,
}) => {
  const dispatch = useDispatch();
  const [paymentData, setPaymentData] = useState([]);
  const [directBuyImages, setDirectBuyImages] = useState([[]]);
  const [localItems, setLocalItems] = useState([
    { amount: "", date: "", image: "" },
  ]);
  const selectedSubUser = useSelector(
    (state) => state.userSlice.selectedSubUser
  );
  const formik = useFormik({
    initialValues: {
      province_kill_request_key: modal_key,
      items: localItems,
    },
    validationSchema: Yup.object({
      items: Yup.array().of(
        Yup.object().shape({
          amount: Yup.number()
            .typeError("مبلغ باید یک عدد معتبر باشد")
            .required("وارد کردن مبلغ الزامی است")
            .positive("مبلغ باید عددی مثبت باشد")
            .integer("مبلغ باید عدد صحیح باشد"),
          date: Yup.date()
            .typeError("تاریخ معتبر وارد کنید")
            .required("تاریخ پرداخت الزامی است")
            .max(new Date(), "تاریخ نمی‌تواند از امروز بیشتر باشد"),
          image: Yup.string().required("بارگزاری سند الزامی است"),
        })
      ),
    }),
    onSubmit: () => {},
    enableReinitialize: true,
  });

  const isItemFilled = useCallback(
    (item) => !!(item.amount || item.date || item.image),
    []
  );

  const handleDateChange = useCallback(
    (date, index) => {
      const formattedDateTime = moment(date).toISOString();
      const newItems = [...localItems];
      newItems[index] = { ...newItems[index], date: formattedDateTime };
      setLocalItems(newItems);
      formik.setFieldValue(`items[${index}].date`, formattedDateTime, false);
    },
    [localItems, formik]
  );

  const handleAmountChange = useCallback(
    (value, index) => {
      const newItems = [...localItems];
      newItems[index] = { ...newItems[index], amount: value };
      setLocalItems(newItems);
      formik.setFieldValue(`items[${index}].amount`, value, false);
    },
    [localItems, formik]
  );

  const directBuyImgHandler = useCallback(
    (imageList, index) => {
      setDirectBuyImages((prev) => {
        const newArr = [...prev];
        newArr[index] = imageList;
        return newArr;
      });

      if (imageList[0]) {
        const file = imageList[0]?.file;
        resizeImage(file, (resizedDataUrl) => {
          const optimizedBase64 = fixBase64(resizedDataUrl);
          const newItems = [...localItems];
          newItems[index] = { ...newItems[index], image: optimizedBase64 };
          setLocalItems(newItems);
          formik.setFieldValue(`items[${index}].image`, optimizedBase64, false);
        });
      } else {
        const newItems = [...localItems];
        newItems[index] = { ...newItems[index], image: "" };
        setLocalItems(newItems);
        formik.setFieldValue(`items[${index}].image`, "", false);
      }
    },
    [localItems, formik]
  );

  const removeFormItem = useCallback(
    (index) => {
      const newItems = localItems.filter((_, i) => i !== index);
      const newImages = directBuyImages.filter((_, i) => i !== index);

      setLocalItems(
        newItems.length ? newItems : [{ amount: "", date: "", image: "" }]
      );
      setDirectBuyImages(newImages.length ? newImages : [[]]);
      formik.setFieldValue(
        "items",
        newItems.length ? newItems : [{ amount: "", date: "", image: "" }],
        false
      );
    },
    [localItems, directBuyImages, formik]
  );

  const validateItem = useCallback(
    async (index) => {
      await formik.setTouched(
        {
          items: formik.values.items.map((item, i) =>
            i === index ? { amount: true, date: true, image: true } : item
          ),
        },
        false
      );

      const errors = await formik.validateForm();
      return !(errors.items && errors.items[index]);
    },
    [formik]
  );

  const submitItem = useCallback(
    async (index) => {
      const item = localItems[index];
      if (!isItemFilled(item)) {
        removeFormItem(index);
        return;
      }
      const isValid = await validateItem(index);
      if (!isValid) return;

      const payload = {
        province_kill_request_key: modal_key,
        amount: item.amount,
        date: item.date,
        image: item.image,
      };

      dispatch(adminSettlementDirectBuying(payload)).then((action) => {
        if (action.payload?.status === 200 || action.payload?.status === 201) {
          const newItems = [...localItems];
          newItems[index] = { amount: "", date: "", image: "" };
          setLocalItems(newItems);

          setDirectBuyImages((prev) => {
            const newArr = [...prev];
            newArr[index] = [];
            return newArr;
          });

          dispatch(
            freeBuyingPayment({
              role_key: checkPathStartsWith("province")
                ? selectedSubUser?.key || ""
                : "",
              province_kill_request_key: modal_key,
            })
          ).then((action) => {
            const response = action.payload?.data;
            if (response && Array.isArray(response)) {
              setPaymentData(
                response.map((p) => ({ ...p, date: formatJustDate(p.date) }))
              );
            }
          });
          updateTable_modal();
        }
      });
    },
    [
      localItems,
      isItemFilled,
      removeFormItem,
      validateItem,
      dispatch,
      modal_key,
      updateTable_modal,
    ]
  );

  useEffect(() => {
    if (!modal_key) return;
    dispatch(
      freeBuyingPayment({
        province_kill_request_key: modal_key,
        role_key: checkPathStartsWith("province")
          ? selectedSubUser?.key || ""
          : "",
      })
    ).then((action) => {
      const response = action.payload?.data;
      if (response && Array.isArray(response)) {
        setPaymentData(
          response.map((p) => ({ ...p, date: formatJustDate(p.date) }))
        );
      }
    });
  }, [dispatch, modal_key]);

  const CardShell = useCallback(
    ({ children, highlight = false }) => (
      <Card
        elevation={0}
        sx={{
          width: "100%",
          maxWidth: 880,
          borderRadius: 3,
          border: "1px solid",
          borderColor: highlight ? "primary.main" : "divider",
          bgcolor: "background.paper",
        }}
      >
        {children}
      </Card>
    ),
    []
  );

  return (
    <Box
      sx={{
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        gap: 2,
        p: 2,
      }}
    >
      {paymentData.map((payment) => (
        <CardShell key={payment.key}>
          <CardContent sx={{ p: 2 }}>
            <Grid container spacing={2} alignItems="center">
              {payment.image && (
                <Grid item>
                  <Box
                    sx={{
                      width: 64,
                      height: 64,
                      borderRadius: 2,
                      overflow: "hidden",
                      border: "1px solid",
                      borderColor: "divider",
                    }}
                  >
                    <ShowImage src={payment.image} />
                  </Box>
                </Grid>
              )}

              <Grid item xs sm={5} md={4}>
                <TextField
                  size="small"
                  fullWidth
                  label="مبلغ"
                  value={payment.amount?.toLocaleString() || ""}
                  InputProps={{
                    readOnly: true,
                    endAdornment: (
                      <InputAdornment position="end">ریال</InputAdornment>
                    ),
                  }}
                />
              </Grid>

              {payment.date && (
                <Grid item xs sm={5} md={4}>
                  <TextField
                    size="small"
                    fullWidth
                    label="تاریخ پرداخت"
                    value={payment.date}
                    InputProps={{ readOnly: true }}
                  />
                </Grid>
              )}

              <Grid
                item
                xs
                sx={{
                  display: "flex",
                  justifyContent: { xs: "flex-start", sm: "flex-end" },
                }}
              >
                <IconButton
                  color="error"
                  aria-label="حذف پرداخت"
                  onClick={() => {
                    dispatch(
                      freeBuyDeletePaymentService({ key: payment.key })
                    ).then((action) => {
                      if (
                        action.payload?.status === 200 ||
                        action.payload?.status === 201
                      ) {
                        setPaymentData((d) =>
                          d.filter((p) => p.key !== payment.key)
                        );
                      }
                    });
                    updateTable_modal();
                  }}
                >
                  <DeleteOutlineIcon />
                </IconButton>
              </Grid>
            </Grid>
          </CardContent>
        </CardShell>
      ))}

      {localItems?.map((item, index) => (
        <CardShell key={index} highlight={isItemFilled(item)}>
          <CardContent sx={{ p: 2 }}>
            <Grid container spacing={2} alignItems="center">
              <Grid item xs={12} sm={4} md={3}>
                <ImageUpload
                  size="small"
                  images={directBuyImages[index] || []}
                  onChange={(imageList) =>
                    directBuyImgHandler(imageList, index)
                  }
                  maxNumber={1}
                  title={"بارگذاری"}
                />
                {formik.touched.items?.[index]?.image &&
                  formik.errors.items?.[index]?.image && (
                    <Typography color="error" variant="caption">
                      {formik.errors.items[index].image}
                    </Typography>
                  )}
              </Grid>

              <Grid item xs={12} sm={4} md={3}>
                <TextField
                  size="small"
                  fullWidth
                  label="مبلغ"
                  value={item.amount || ""}
                  onChange={(e) => handleAmountChange(e.target.value, index)}
                  onBlur={formik.handleBlur}
                  error={
                    formik.touched.items?.[index]?.amount &&
                    Boolean(formik.errors.items?.[index]?.amount)
                  }
                  helperText={
                    formik.touched.items?.[index]?.amount &&
                    formik.errors.items?.[index]?.amount
                  }
                  InputProps={{
                    inputMode: "numeric",
                    endAdornment: (
                      <InputAdornment position="end">ریال</InputAdornment>
                    ),
                  }}
                />
              </Grid>

              <Grid item xs={12} sm={4} md={3}>
                <DatePicker
                  label="تاریخ پرداخت"
                  value={item.date ? moment(item.date) : null}
                  onChange={(d) => handleDateChange(d, index)}
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      size="small"
                      fullWidth
                      onBlur={formik.handleBlur}
                      error={
                        formik.touched.items?.[index]?.date &&
                        Boolean(formik.errors.items?.[index]?.date)
                      }
                      helperText={
                        formik.touched.items?.[index]?.date &&
                        formik.errors.items?.[index]?.date
                      }
                    />
                  )}
                />
              </Grid>

              <Grid
                item
                xs
                display="flex"
                justifyContent={{ xs: "flex-start", sm: "flex-end" }}
                gap={0.5}
              >
                <Stack direction="row" spacing={0.5}>
                  {isItemFilled(item) && formik.values.items?.[index]?.date && (
                    <IconButton
                      aria-label="ثبت آیتم"
                      onClick={() => submitItem(index)}
                      disabled={formik.isSubmitting}
                      sx={{
                        border: "1px solid",
                        borderColor: isItemFilled(item)
                          ? "primary.main"
                          : "warning.main",
                      }}
                    >
                      <DoneIcon color="primary" />
                    </IconButton>
                  )}
                </Stack>
              </Grid>
            </Grid>
          </CardContent>
        </CardShell>
      ))}

      {(paymentData?.length > 0 || localItems?.length > 0) && (
        <CardShell>
          <CardContent sx={{ p: 2 }}>
            <Stack
              direction="row"
              alignItems="center"
              justifyContent="space-between"
              gap={2}
            >
              <Typography variant="subtitle1">مبلغ کل</Typography>
              <Divider flexItem />
              <Typography variant="h6" color="primary">
                {(
                  paymentData?.reduce((sum, p) => sum + (p?.amount || 0), 0) +
                  (localItems?.reduce(
                    (sum, it) => sum + (Number(it.amount) || 0),
                    0
                  ) || 0)
                )?.toLocaleString()}{" "}
                ریال
              </Typography>
            </Stack>
          </CardContent>
        </CardShell>
      )}
    </Box>
  );
};
