import { zodResolver } from "@hookform/resolvers/zod";
import Button from "../../components/Button/Button";
import { Grid } from "../../components/Grid/Grid";
import Textfield from "../../components/Textfeild/Textfeild";
import { useForm, Controller } from "react-hook-form";
import {
  zValidateAutoComplete,
  zValidateNumber,
  zValidateStringOptional,
} from "../../data/getFormTypeErrors";
import { z } from "zod";
import { useToast } from "../../hooks/useToast";
import { useModalStore } from "../../context/zustand-store/appStore";
import { getToastResponse } from "../../data/getToastResponse";
import { FormApiBasedAutoComplete } from "../../components/FormItems/FormApiBasedAutoComplete";
import { useApiMutation } from "../../utils/useApiRequest";
import Typography from "../../components/Typography/Typography";
import Checkbox from "../../components/CheckBox/CheckBox";
import { useState, useEffect } from "react";

type Props = {
  getData: () => void;
  item?: any;
  code?: string;
  remainWeight?: number;
  quota?: any;
};

export const QuotaDistribution = ({
  getData,
  item,
  code,
  remainWeight,
  quota,
}: Props) => {
  const showToast = useToast();
  const { closeModal } = useModalStore();
  const [editPriceComponents, setEditPriceComponents] = useState(false);
  const [attributeValues, setAttributeValues] = useState<
    Record<number, number>
  >({});
  const [brokerValues, setBrokerValues] = useState<Record<number, number>>({});
  const [initialAttributeSum, setInitialAttributeSum] = useState<number>(0);
  const [initialBrokerSum, setInitialBrokerSum] = useState<number>(0);

  useEffect(() => {
    if (quota?.attribute_values) {
      const attrs: Record<number, number> = {};
      let sum = 0;
      quota.attribute_values.forEach((attr: any) => {
        attrs[attr.attribute] = attr.value;
        sum += attr.value;
      });
      setAttributeValues(attrs);
      setInitialAttributeSum(sum);
    }
    if (quota?.brokers) {
      const brokers: Record<number, number> = {};
      let sum = 0;
      quota.brokers.forEach((broker: any) => {
        brokers[broker.broker] = broker.value;
        sum += broker.value;
      });
      setBrokerValues(brokers);
      setInitialBrokerSum(sum);
    }
  }, [quota]);

  const schema = z.object({
    weight: zValidateNumber("وزن"),
    description: zValidateStringOptional("توضیحات"),
    organization: zValidateAutoComplete("سازمان"),
  });

  type FormValues = z.infer<typeof schema>;

  const {
    control,
    handleSubmit,
    setValue,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      weight: item?.weight || "",
      organization: item?.assigned_organization
        ? [item?.assigned_organization]
        : [],
      description: item?.description || "",
    },
  });

  const mutation = useApiMutation({
    api: `/product/web/api/v1/quota_distribution/${item ? item?.id + "/" : ""}`,
    method: item ? "put" : "post",
  });

  const onSubmit = async (data: FormValues) => {
    try {
      if (editPriceComponents) {
        const currentAttributeSum = Object.values(attributeValues).reduce(
          (sum, val) => sum + val,
          0
        );
        const currentBrokerSum = Object.values(brokerValues).reduce(
          (sum, val) => sum + val,
          0
        );

        if (currentAttributeSum !== initialAttributeSum) {
          showToast(
            `مجموع قیمت مولفه های قیمت گذاری باید برابر ${initialAttributeSum.toLocaleString()} باشد. مجموع فعلی: ${currentAttributeSum.toLocaleString()}`,
            "error"
          );
          return;
        }

        if (currentBrokerSum !== initialBrokerSum) {
          showToast(
            `مجموع قیمت کارگزاران باید برابر ${initialBrokerSum.toLocaleString()} باشد. مجموع فعلی: ${currentBrokerSum.toLocaleString()}`,
            "error"
          );
          return;
        }
      }

      const payload: any = {
        weight: data.weight,
        assigned_organization: data.organization[0],
        quota: code ? parseInt(code) : 0,
        description: data.description,
      };

      if (editPriceComponents) {
        payload.price_attributes_data = Object.keys(attributeValues).map(
          (key) => ({
            attribute: parseInt(key),
            value: attributeValues[parseInt(key)],
          })
        );
        payload.broker_data = Object.keys(brokerValues).map((key) => ({
          broker: parseInt(key),
          value: brokerValues[parseInt(key)],
        }));
      }

      await mutation.mutateAsync(payload);
      showToast(getToastResponse(item, ""), "success");
      getData();
      closeModal();
    } catch (error: any) {
      if (error?.status === 400) {
        showToast(
          error?.response?.data?.detail || error?.response?.data?.message,
          "error"
        );
        closeModal();
      } else if (error?.status === 403) {
        showToast(
          error?.response?.data?.message || "این مورد تکراری است!",
          "error"
        );
      } else {
        showToast(
          error?.response?.data?.message || "خطا در ثبت اطلاعات!",
          "error"
        );
      }
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Grid container column className="gap-2">
        <Grid container className="justify-center w-full">
          <Typography variant="body2" className="items-center" sign="info">
            {" "}
            مانده قابل توزیع:
            <span className="font-bold text-red-500">{remainWeight} </span>
          </Typography>
        </Grid>

        <Controller
          name="weight"
          control={control}
          render={({ field }) => (
            <Textfield
              formattedNumber
              fullWidth
              placeholder="وزن"
              value={field.value}
              onChange={field.onChange}
              error={!!errors.weight}
              helperText={errors.weight?.message}
            />
          )}
        />

        <Controller
          name="organization"
          control={control}
          render={() => (
            <FormApiBasedAutoComplete
              defaultKey={item?.assigned_organization}
              groupBy={["type", "name"]}
              title="سازمان"
              api={
                item
                  ? "auth/api/v1/organization/child_organizations"
                  : `auth/api/v1/organization/child_organizations_for_distribute/?quota_id=${code}`
              }
              keyField="id"
              valueField="name"
              error={!!errors.organization}
              errorMessage={errors.organization?.message}
              onChange={(r) => {
                setValue("organization", [r]);
              }}
            />
          )}
        />

        <Controller
          name="description"
          control={control}
          render={({ field }) => (
            <Textfield
              fullWidth
              placeholder="توضیحات (اختیاری)"
              value={field.value}
              onChange={field.onChange}
              error={!!errors.description}
              helperText={errors.description?.message}
            />
          )}
        />

        <Checkbox
          label="ویرایش مولفه های قیمت گذاری"
          checked={editPriceComponents}
          onChange={(e) => setEditPriceComponents(e.target.checked)}
        />

        {editPriceComponents && (
          <>
            <Grid container className="justify-start w-full">
              <Typography variant="body2" className="items-center">
                مولفه های قیمت گذاری:
              </Typography>
            </Grid>

            {quota?.attribute_values?.map((attr: any) => (
              <Textfield
                key={attr.id}
                formattedNumber
                fullWidth
                placeholder={attr.attribute_name}
                value={attributeValues[attr.attribute] ?? ""}
                onChange={(e) => {
                  setAttributeValues((prev) => ({
                    ...prev,
                    [attr.attribute]: parseInt(e.target.value) || 0,
                  }));
                }}
                end="ریال"
              />
            ))}

            <Grid container className="justify-start w-full">
              <Typography variant="body2" className="items-center">
                مجموع مولفه های قیمت:{" "}
                <span
                  className={
                    Object.values(attributeValues).reduce(
                      (sum, val) => sum + val,
                      0
                    ) === initialAttributeSum
                      ? "text-green-500"
                      : "text-red-500"
                  }
                >
                  {Object.values(attributeValues)
                    .reduce((sum, val) => sum + val, 0)
                    .toLocaleString()}
                </span>
                {" / "}
                <span className="text-gray-500">
                  {initialAttributeSum.toLocaleString()}
                </span>
              </Typography>
            </Grid>

            <Grid container className="justify-start w-full">
              <Typography variant="body2" className="items-center">
                کارگزاران:
              </Typography>
            </Grid>

            {quota?.brokers?.map((broker: any) => (
              <Textfield
                key={broker.id}
                formattedNumber
                fullWidth
                placeholder={broker.broker_name}
                value={brokerValues[broker.broker] ?? ""}
                onChange={(e) => {
                  setBrokerValues((prev) => ({
                    ...prev,
                    [broker.broker]: parseInt(e.target.value) || 0,
                  }));
                }}
                end="ریال"
              />
            ))}

            <Grid container className="justify-start w-full">
              <Typography variant="body2" className="items-center">
                مجموع کارگزاران:{" "}
                <span
                  className={
                    Object.values(brokerValues).reduce(
                      (sum, val) => sum + val,
                      0
                    ) === initialBrokerSum
                      ? "text-green-500"
                      : "text-red-500"
                  }
                >
                  {Object.values(brokerValues)
                    .reduce((sum, val) => sum + val, 0)
                    .toLocaleString()}
                </span>
                {" / "}
                <span className="text-gray-500">
                  {initialBrokerSum.toLocaleString()}
                </span>
              </Typography>
            </Grid>
          </>
        )}

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