import {
  Button,
  Checkbox,
  FormControl,
  FormControlLabel,
  FormHelperText,
  Grid,
  InputLabel,
  ListItem,
  ListItemIcon,
  ListItemText,
  MenuItem,
  Select,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers";
import DoneIcon from "@mui/icons-material/Done";
import { useEffect, useState, useContext } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useFormik } from "formik";
import moment from "moment";

import { SPACING } from "../../../../data/spacing";
import { Yup } from "../../../../lib/yup/yup";
import {
  CLOSE_MODAL,
  DRAWER,
  LOADING_END,
  LOADING_START,
  OPEN_MODAL,
} from "../../../../lib/redux/slices/appSlice";
import { AppContext } from "../../../../contexts/AppContext";
import { DialogAlert } from "../../../../components/dialog-alert/DialogAlert";
import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom";
import useUserProfile from "../../../authentication/hooks/useUserProfile";
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
import { slaughterNewRequest } from "../../services/slaughter-new-request";
import { slaughterGetRequests } from "../../services/salughter-get-requests";
import { slaughterGetProfile } from "../../services/slaughter-get-profile";
import { slaughterGetKillerKillhousesService } from "../../services/slaughter-get-killers-killhouses";
import { provinceGetPricing } from "../../../province/services/province-get-pricing";
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";

const TIME_RANGES = [
  "12 - 14",
  "14 - 16",
  "16 - 18",
  "18 - 20",
  "20 - 22",
  "22 - 24",
];

const CHICKEN_BREEDS = [
  "آرین",
  "راس",
  "آربراکرز (آپلاس)",
  "کاب",
  "هوبارد",
  "ترکیبی",
  "وارداتی",
];

const DEFAULT_INDEX_WEIGHT = 2.7;
const PENALTY_MULTIPLIER = 1000;
const SMS_COST = "5000 تومان";

const getInitialValues = (selectedSubUser) => ({
  capacity: "",
  recieveTime: "",
  selectedKillhouse: selectedSubUser?.key || "",
  selectedKillerKillhouse: "",
  race: CHICKEN_BREEDS[0],
  sellType: {
    cash: true,
    haveTime: false,
  },
  weightType: {
    under2AndHalf: false,
    over2AndHalf: false,
  },
  recieveDate: moment().format("YYYY-MM-DD hh:mm:ss"),
  isAccepted: getRoleFromUrl() === "ProvinceOperator",
  indexWeight: DEFAULT_INDEX_WEIGHT,
});

const getValidationSchema = (selectedSubUser) =>
  Yup.object({
    capacity: Yup.number()
      .required("این فیلد اجباری است!")
      .typeError("لطفا عدد وارد کنید!"),
    selectedKillhouse: Yup.string().required("این فیلد اجباری است!"),
    selectedKillerKillhouse: selectedSubUser?.killer
      ? Yup.string().required("این فیلد اجباری است!")
      : Yup.string(),
    recieveTime: Yup.string()
      .required("این فیلد اجباری است!")
      .typeError("لطفا وزن را وارد کنید!"),
    sellType: Yup.object()
      .test("sellType", "نحوه فروش را انتخاب کنید!", (val, context) => {
        return (
          context.originalValue &&
          Object.values(context.originalValue).some((item) => item === true)
        );
      })
      .required("این فیلد اجباری است!"),
    isAccepted: Yup.boolean()
      .test("req", "باید تعهد نامه را بپذیرید!", (val, context) => {
        return context.originalValue && context.originalValue === true;
      })
      .required("این فیلد اجباری است!"),
  });

export const SlaughterNewRequestForm = () => {
  const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext);
  const dispatch = useDispatch();
  const [, userProfile] = useUserProfile();
  const { profile, slaughterGetKillerKillhouses } = useSelector(
    (state) => state.slaughterSlice
  );
  const selectedSubUser = useSelector(
    (state) => state.userSlice.selectedSubUser
  );

  const [checkedSms, setCheckedSms] = useState(true);
  const [checkedBreedAndWeight, setCheckedBreedAndWeight] = useState(false);

  const formik = useFormik({
    initialValues: getInitialValues(selectedSubUser),
    validationSchema: getValidationSchema(selectedSubUser),
  });

  const penaltyPrice = formik.values.capacity * PENALTY_MULTIPLIER;

  const dialogContent = (
    <>
      <Typography variant="body1">
        اینجانب {userProfile.fullname} موافقت خود را نسبت به موارد ذکر شده اعلام
        می نمایم.
      </Typography>
      <ListItem>
        <ListItemIcon>
          <DoneIcon />
        </ListItemIcon>
        <ListItemText
          primary={`بر اساس این توافق نامه در صورت لغو کشتار ${formik.values.capacity} قطعه
        مرغ ${penaltyPrice} ریال جریمه خواهم شد.`}
        />
      </ListItem>
    </>
  );

  useEffect(() => {
    dispatch(
      slaughterGetKillerKillhousesService({
        role_key: checkPathStartsWith("slaughter")
          ? selectedSubUser?.key || ""
          : "",
      })
    );
    dispatch(LOADING_START());
    dispatch(
      slaughterGetProfile({
        role_key: checkPathStartsWith("slaughter")
          ? selectedSubUser?.key || ""
          : "",
      })
    ).then(() => {
      dispatch(LOADING_END());
    });
    dispatch(provinceGetPricing());
    formik.validateForm();
  }, [selectedSubUser?.key]);

  const handleSubmit = async () => {
    dispatch(LOADING_START());
    const result = await dispatch(
      slaughterNewRequest({
        kill_capacity: formik.values.capacity,
        recive_time: formik.values.recieveTime,
        recive_date: formik.values.recieveDate,
        low_weight: formik.values.weightType.under2AndHalf,
        high_weight: formik.values.weightType.over2AndHalf,
        Index_weight: checkedBreedAndWeight
          ? formik.values.indexWeight
          : DEFAULT_INDEX_WEIGHT,
        chicken_breed: checkedBreedAndWeight
          ? formik.values.race
          : "تعیین نشده",
        cash: formik.values.sellType.cash,
        credit: formik.values.sellType.haveTime,
        sms_payment: checkedSms,
        kill_house_key: formik.values.selectedKillhouse,
        killer_kill_house_key: formik.values.selectedKillerKillhouse || null,
        role: getRoleFromUrl(),
      })
    );

    dispatch(LOADING_END());

    if (result.payload.error) {
      openNotif({
        vertical: "top",
        horizontal: "center",
        msg: result.payload.error,
        severity: "error",
      });
      return;
    }

    dispatch(
      slaughterGetRequests({
        selectedDate1,
        selectedDate2,
        role_key: checkPathStartsWith("slaughter")
          ? selectedSubUser?.key || ""
          : "",
      })
    );
    dispatch(
      OPEN_MODAL({
        title: result.payload.data.result,
        content: (
          <Button
            variant="contained"
            onClick={() => dispatch(CLOSE_MODAL())}
            color="primary"
          >
            تایید
          </Button>
        ),
      })
    );
    openNotif({
      vertical: "top",
      horizontal: "center",
      msg: "عملیات با موفقیت انجام شد.",
      severity: "success",
    });
    dispatch(DRAWER({ right: false, bottom: false, content: null }));
  };

  const isProvinceOperator = getRoleFromUrl() === "ProvinceOperator";

  return (
    <Grid
      className="slaughter-new-request-form"
      container
      gap={SPACING.SMALL}
      direction="column"
      flex="1"
      justifyContent="space-between"
    >
      <Grid container direction="column" gap={SPACING.SMALL}>
        {!selectedSubUser?.key && (
          <FormControl
            fullWidth
            error={
              formik.errors.selectedKillhouse &&
              formik.touched.selectedKillhouse
            }
          >
            <InputLabel>
              {selectedSubUser?.killer ? "کشتارکن" : "محل کشتار"} را انتخاب کنید
            </InputLabel>
            <Select
              label="محل کشتار را انتخاب کنید"
              id="selectedKillhouse"
              name="selectedKillhouse"
              value={formik.values.selectedKillhouse}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            >
              {profile?.killHouse?.map((option) => (
                <MenuItem key={option.key} value={option.key}>
                  {option.name}
                </MenuItem>
              ))}
            </Select>
            {formik.errors.selectedKillhouse &&
              formik.touched.selectedKillhouse && (
                <FormHelperText>
                  {formik.errors.selectedKillhouse}
                </FormHelperText>
              )}
          </FormControl>
        )}

        {selectedSubUser?.killer && (
          <FormControl
            fullWidth
            error={
              formik.errors.selectedKillerKillhouse &&
              formik.touched.selectedKillerKillhouse
            }
          >
            <InputLabel>محل کشتار را انتخاب کنید</InputLabel>
            <Select
              label="محل کشتار را انتخاب کنید"
              id="selectedKillerKillhouse"
              name="selectedKillerKillhouse"
              value={formik.values.selectedKillerKillhouse}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
            >
              {slaughterGetKillerKillhouses?.map((option) => (
                <MenuItem key={option.key} value={option.key}>
                  {option.name}
                </MenuItem>
              ))}
            </Select>
            {formik.errors.selectedKillerKillhouse &&
              formik.touched.selectedKillerKillhouse && (
                <FormHelperText>
                  {formik.errors.selectedKillerKillhouse}
                </FormHelperText>
              )}
          </FormControl>
        )}

        <Grid>
          <NumberInput
            allowLeadingZeros
            thousandSeparator=","
            id="capacity"
            fullWidth
            label="حجم کشتار را در روز به قطعه وارد کنید"
            variant="outlined"
            value={formik.values.capacity}
            error={
              formik.touched.capacity ? Boolean(formik.errors.capacity) : null
            }
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            helperText={
              formik.touched.capacity && Boolean(formik.errors.capacity)
                ? formik.errors.capacity
                : null
            }
          />
        </Grid>

        <Grid>
          <FormControl fullWidth sx={{ minWidth: 210 }}>
            <InputLabel>بازه زمانی دریافت مرغ مرغدار</InputLabel>
            <Select
              id="recieveTime"
              value={formik.values.recieveTime}
              label="بازه زمانی دریافت مرغ مرغدار"
              onChange={(e) => {
                formik.setFieldValue("recieveTime", e.target.value);
              }}
            >
              {TIME_RANGES.map((range) => (
                <MenuItem key={range} value={range}>
                  {range}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </Grid>

        <Grid>
          <DatePicker
            label="تاریخ کشتار"
            id="recieveDate"
            renderInput={(params) => <TextField {...params} />}
            value={formik.values.recieveDate}
            error={
              formik.touched.recieveDate
                ? Boolean(formik.errors.recieveDate)
                : null
            }
            onChange={(e) => {
              formik.setFieldValue(
                "recieveDate",
                moment(e).format("YYYY-MM-DD hh:mm:ss")
              );
            }}
            onBlur={formik.handleBlur}
            helperText={
              formik.touched.recieveDate && Boolean(formik.errors.recieveDate)
                ? formik.errors.recieveDate
                : null
            }
          />
        </Grid>
      </Grid>

      <FormControlLabel
        control={
          <Checkbox
            checked={checkedBreedAndWeight}
            onChange={(e) => setCheckedBreedAndWeight(e.target.checked)}
            color="primary"
          />
        }
        label="تعیین نژاد/وزن مرغ"
      />

      {checkedBreedAndWeight && (
        <Grid container direction="column" gap={SPACING.TINY}>
          <FormControl fullWidth>
            <InputLabel id="race-select-label">نژاد مرغ</InputLabel>
            <Select
              labelId="race-select-label"
              id="race"
              label="نژاد مرغ"
              value={formik.values.race}
              error={formik.touched.race ? Boolean(formik.errors.race) : null}
              onChange={(e) => {
                formik.setFieldValue("race", e.target.value);
              }}
              onBlur={formik.handleBlur}
            >
              {CHICKEN_BREEDS.map((breed) => (
                <MenuItem key={breed} value={breed}>
                  {breed}
                </MenuItem>
              ))}
            </Select>
            <FormHelperText>
              {formik.touched.race && Boolean(formik.errors.race)
                ? formik.errors.race
                : null}
            </FormHelperText>
          </FormControl>

          <Grid>
            <NumberInput
              allowLeadingZeros
              thousandSeparator=","
              id="indexWeight"
              fullWidth
              label="وزن مرغ"
              variant="outlined"
              value={formik.values.indexWeight}
              error={
                formik.touched.indexWeight
                  ? Boolean(formik.errors.indexWeight)
                  : null
              }
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
              helperText={
                formik.touched.indexWeight && Boolean(formik.errors.indexWeight)
                  ? formik.errors.indexWeight
                  : null
              }
            />
          </Grid>
        </Grid>
      )}

      <Grid>
        {!isProvinceOperator && (
          <DialogAlert
            title="تعهد نامه"
            content={dialogContent}
            actions={
              <Grid container justifyContent="end" gap={SPACING.TINY}>
                <Button
                  variant="outlined"
                  color="error"
                  onClick={() => formik.setFieldValue("isAccepted", false)}
                >
                  رد
                </Button>
                <Button
                  variant="contained"
                  color="success"
                  onClick={() => formik.setFieldValue("isAccepted", true)}
                >
                  موافقم
                </Button>
              </Grid>
            }
            btnTitle="با تعهد نامه موافق هستم!"
            isAccepted={formik.values.isAccepted}
          />
        )}

        <Grid>
          <FormControlLabel
            style={{ fontSize: "10px" }}
            control={
              <Checkbox
                checked={checkedSms}
                onChange={(e) => setCheckedSms(e.target.checked)}
              />
            }
            label={
              <Tooltip title={SMS_COST} arrow>
                <Typography variant="caption">
                  مایل به دریافت پیامک اطلاع رسانی هستم!
                </Typography>
              </Tooltip>
            }
          />
        </Grid>
      </Grid>

      <Grid container mt={SPACING.SMALL} justifyContent="center">
        <Button
          fullWidth
          variant="contained"
          disabled={!formik.isValid}
          size="large"
          onClick={handleSubmit}
        >
          ثبت درخواست
        </Button>
      </Grid>
    </Grid>
  );
};
