import React, { useContext, useEffect, useState, useCallback } from "react";
import { useFormik } from "formik";
import { useDispatch } from "react-redux";
import {
  Button,
  Box,
  Typography,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
} from "@mui/material";
import { Add as AddIcon } from "@mui/icons-material";
import { Grid } from "../../../../components/grid/Grid";
import { SPACING } from "../../../../data/spacing";
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
import { AppContext } from "../../../../contexts/AppContext";
import { updateGuildByNationalIdNewService } from "../../services/update-guild-by-national-id-new";
import { deactivateGuildService } from "../../services/deactivate-guild";
import { provinceGetCitiesService } from "../../services/province-get-cities";
import { provinceGetFieldOfWorks } from "../../services/ProvinceGetFieldOfWorks";
import { provinceGetTypeActivity } from "../../services/provinceGetTypeActivity";
import { provinceGetRegisterCodeStateService } from "../../services/province-get-register-code-state";
import { mainGetGuildsForUpdateOrCreateService } from "../../services/main-get-guilds-for-update-or-create";
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
import { PersonalInfoSection } from "./components/PersonalInfoSection";
import { InquiryForm } from "./components/InquiryForm";
import { UpdateFromExternalButton } from "./components/UpdateFromExternalButton";
import { ConfirmationDialog } from "./components/ConfirmationDialog";
import { FormActions } from "./components/FormActions";
import { GuildInfoAccordionItem } from "./components/GuildInfoAccordionItem";
import { getValidationSchema, getInitialValues } from "./utils/formUtils";
import {
  mapResponseDataToFormFields,
  prepareSubmitData,
  mapExternalApiGuildToFormValues,
} from "./utils/dataMapping";
import { handleSubmitSuccess, handleSubmitError } from "./utils/submitHandlers";

const DeleteConfirmationDialog = ({ open, onClose, onConfirm, isDeleting }) => {
  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle>آیا مطمئن هستید؟</DialogTitle>
      <DialogContent>
        <Typography variant="body2">
          آیا از حذف این صنف مطمئن هستید؟ این عمل قابل بازگشت نیست.
        </Typography>
      </DialogContent>
      <DialogActions sx={{ gap: 2, p: 2 }}>
        <Button
          variant="outlined"
          onClick={onClose}
          disabled={isDeleting}
          sx={{ flex: 1 }}
        >
          انصراف
        </Button>
        <Button
          variant="contained"
          color="error"
          onClick={onConfirm}
          disabled={isDeleting}
          sx={{ flex: 1 }}
        >
          {isDeleting ? "در حال حذف..." : "حذف"}
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export const CreateGuilds = ({ guild, updateTable }) => {
  const dispatch = useDispatch();
  const [openNotif] = useContext(AppContext);
  const [hasRegisterCode, setHasRegisterCode] = useState();
  const [inquiryNationalCode, setInquiryNationalCode] = useState("");
  const [isInquiryDone, setIsInquiryDone] = useState(false);
  const [dbRegister, setDbRegister] = useState(null);
  const [hasInquiry, setHasInquiry] = useState(null);
  const [guildActive, setGuildActive] = useState(null);
  const [guildsList, setGuildsList] = useState(() => (guild ? [guild] : []));
  const [expandedAccordion, setExpandedAccordion] = useState(0);
  const [guildsFormValues, setGuildsFormValues] = useState(() => {
    // Initialize with guild data if editing
    if (guild) {
      return [getInitialValues(guild)];
    }
    return [];
  });
  const [cities, setCities] = useState([]);
  const [typeActivities, setTypeActivities] = useState([]);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [deleteDialogIndex, setDeleteDialogIndex] = useState(null);
  const [isDeletingGuild, setIsDeletingGuild] = useState(false);

  const originalPhoneNumber = guild?.phoneNumber || null;

  const currentRole = getRoleFromUrl();
  const isAdmin = currentRole === "AdminX";
  const isSuperAdmin = currentRole === "SuperAdmin";
  const isKillHouse = currentRole === "KillHouse";

  const formik = useFormik({
    initialValues: getInitialValues(guild),
    validationSchema: getValidationSchema(!!guild),
    validateOnMount: true,
    onSubmit: (values) => {
      const guildsDataArray = guildsList.map((guildItem, index) => {
        const guildValues = guildsFormValues[index] || values;
        const combinedValues = {
          ...values, // Personal info (shared)
          ...guildValues, // Guild-specific info (overrides if same keys exist)
          national_id: values?.national_id,
          gender: values?.gender,
          first_name: values?.first_name,
          last_name: values?.last_name,
          national_code: values?.national_code,
          is_alive: values?.is_alive,
          birth_date: values?.birth_date,
          father_name: values?.father_name,
          mobile: values?.mobile,
          person_city: values?.person_city,
          city: values?.city,
        };
        return prepareSubmitData(
          combinedValues,
          guildItem,
          originalPhoneNumber,
          hasInquiry
        );
      });

      dispatch(updateGuildByNationalIdNewService(guildsDataArray)).then(
        (result) => {
          if (result.payload.error) {
            handleSubmitError(openNotif, result.payload.error);
            return;
          }
          const data = result.payload?.data;
          const hasPayloadErrors =
            data?.error_count > 0 || (data?.errors?.length ?? 0) > 0;
          if (hasPayloadErrors && data?.errors?.length > 0) {
            const firstError = data.errors[0];
            const message =
              typeof firstError === "string"
                ? firstError
                : firstError?.result || firstError?.message || "خطا در ثبت";
            handleSubmitError(openNotif, message);
            return;
          }
          handleSubmitSuccess(
            dispatch,

            openNotif,
            updateTable,
            values,
            data
          );
        }
      );
    },
  });

  useEffect(() => {
    dispatch(provinceGetRegisterCodeStateService()).then((r) => {
      const isActive = r.payload.data?.[0]?.active;
      setHasRegisterCode(isActive);
      if (isActive === false) {
        formik.setFieldValue("isAccepted", true);
      }
    });
    dispatch(provinceGetCitiesService()).then((r) => {
      setCities(r.payload.data || []);
    });
    dispatch(provinceGetFieldOfWorks());
    dispatch(provinceGetTypeActivity()).then((r) => {
      setTypeActivities(r.payload.data || []);
    });
  }, []);

  useEffect(() => {
    // Initialize Formik's guilds array if we have initial guild data
    if (guild && guildsList.length > 0) {
      const guildsForFormik = guildsList.map((guildItem) => {
        const combinedGuild = {
          ...guildItem,
          user: guild?.user || {},
        };
        const initialValues = getInitialValues(combinedGuild);
        return {
          steward: initialValues.steward || false,
          guild: initialValues.guild || false,
          license_number: initialValues.license_number ?? "",
        };
      });
      formik.setFieldValue("guilds", guildsForFormik, false).then(() => {
        formik.validateField("guilds");
      });
    }
    formik.validateForm();
  }, []);

  // Set city key from person_city name when cities are loaded (e.g. from DB/edit)
  useEffect(() => {
    if (formik.values.person_city && !formik.values.city && cities.length > 0) {
      const city = cities.find(
        (c) =>
          (c.name || "").trim() === (formik.values.person_city || "").trim()
      );
      if (city) {
        formik.setFieldValue("city", city.key ?? city.id ?? "");
      }
    }
  }, [cities, formik.values.person_city, formik.values.city]);

  const mapResponseToFormFields = useCallback(
    (responseData) => {
      const guildsData = Array.isArray(responseData.guilds)
        ? responseData.guilds
        : [];

      mapResponseDataToFormFields(responseData, inquiryNationalCode, formik);

      if (responseData.dbRegister === false) {
        setDbRegister(false);
        setHasInquiry(null);
        if (guildsData.length > 0) {
          setGuildActive(guildsData[0]?.active ?? true);
        }
      } else {
        setHasInquiry(responseData.hasInquiry ?? null);
        const firstGuild = guildsData.length > 0 ? guildsData[0] : null;
        const activeStatus = firstGuild?.active ?? responseData.active ?? null;
        setGuildActive(activeStatus);
        formik.setFieldValue("active", activeStatus);
        setDbRegister(true);
      }

      if (guildsData.length > 0) {
        setGuildsList(guildsData);
        const initialGuildValues =
          responseData.dbRegister === false
            ? guildsData.map((g) => mapExternalApiGuildToFormValues(g))
            : guildsData.map((guildItem) => {
                const combinedGuild = {
                  ...guildItem,
                  user: responseData.user || {},
                };
                return getInitialValues(combinedGuild);
              });
        setGuildsFormValues(initialGuildValues);

        // Update Formik's guilds array for validation (include validated fields)
        const guildsForFormik = initialGuildValues.map((g) => ({
          steward: g.steward ?? false,
          guild: g.guild ?? false,
          license_number: g.license_number ?? "",
        }));
        formik.setFieldValue("guilds", guildsForFormik, true).then(() => {
          formik.validateField("guilds");
        });

        setExpandedAccordion(0);
      } else {
        setGuildsList([]);
        setGuildsFormValues([]);

        formik.setFieldValue("guilds", [], true).then(() => {
          formik.validateField("guilds");
        });
      }

      setTimeout(() => {
        formik.validateField("mobile");
        formik.validateField("national_id");
      }, 0);
    },
    [formik, inquiryNationalCode]
  );

  const handleInquiry = useCallback(() => {
    if (!inquiryNationalCode) {
      openNotif({
        vertical: "top",
        horizontal: "center",
        msg: "لطفا کد ملی را وارد کنید",
        severity: "error",
      });
      return;
    }

    if (!isAdmin && inquiryNationalCode.length !== 10) {
      openNotif({
        vertical: "top",
        horizontal: "center",
        msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید",
        severity: "error",
      });
      return;
    }

    dispatch(
      mainGetGuildsForUpdateOrCreateService({
        national_code: inquiryNationalCode,
        update: false,
      })
    ).then((r) => {
      if (r.payload.error) {
        setHasInquiry(false);
        if (isAdmin) {
          setIsInquiryDone(true);
          formik.setFieldValue("national_id", inquiryNationalCode);
        }
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: r.payload.error,
          severity: "error",
        });
        if (!isAdmin) {
          return;
        }
      }

      if (r.payload.data) {
        mapResponseToFormFields(r.payload.data);
        setIsInquiryDone(true);

        if (r.payload.data.dbRegister === false) {
          setHasInquiry(true);
        }

        const successMsg =
          r.payload.data.dbRegister === false
            ? "اطلاعات از سامانه خارجی دریافت شد"
            : "اطلاعات از پایگاه داده دریافت شد";

        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: successMsg,
          severity: "success",
        });
      } else {
        setHasInquiry(false);
        setIsInquiryDone(true);
        if (isAdmin) {
          formik.setFieldValue("national_id", inquiryNationalCode);
        }
      }
    });
  }, [
    dispatch,
    inquiryNationalCode,
    openNotif,
    mapResponseToFormFields,
    isAdmin,
    formik,
  ]);

  const handleUpdateFromExternal = useCallback(() => {
    if (!formik.values.national_id || formik.values.national_id.length !== 10) {
      openNotif({
        vertical: "top",
        horizontal: "center",
        msg: "لطفا کد ملی 10 رقمی معتبر وارد کنید",
        severity: "error",
      });
      return;
    }

    dispatch(
      mainGetGuildsForUpdateOrCreateService({
        national_code: formik.values.national_id,
        update: true,
      })
    ).then((r) => {
      if (r.payload.error) {
        setHasInquiry(false);
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: r.payload.error,
          severity: "error",
        });
        return;
      }

      if (r.payload.data) {
        const updateResponse = {
          ...r.payload.data,
          dbRegister: false,
        };
        mapResponseToFormFields(updateResponse);
        setHasInquiry(true);

        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: "اطلاعات از سامانه خارجی بروزرسانی شد",
          severity: "success",
        });
      } else {
        setHasInquiry(false);
      }
    });
  }, [dispatch, formik.values.national_id, openNotif, mapResponseToFormFields]);

  const handleAddGuild = () => {
    const newIndex = guildsList.length;
    setGuildsList([...guildsList, null]);
    setGuildsFormValues([...guildsFormValues, getInitialValues(null)]);

    // Add to Formik's guilds array for validation
    const currentGuilds = formik.values.guilds || [];
    formik
      .setFieldValue(
        "guilds",
        [...currentGuilds, { steward: false, guild: false }],
        true
      )
      .then(() => {
        formik.validateField("guilds");
      });

    setExpandedAccordion(newIndex);
  };

  const handleDeleteGuild = (index) => {
    const guildToDelete = guildsList[index];
    if (guildToDelete?.key) {
      setDeleteDialogIndex(index);
      setDeleteDialogOpen(true);
      return;
    }
    if (guildsList.length > 1) {
      setGuildsList(guildsList.filter((_, i) => i !== index));
      setGuildsFormValues(guildsFormValues.filter((_, i) => i !== index));

      // Remove from Formik's guilds array
      const currentGuilds = formik.values.guilds || [];
      formik
        .setFieldValue(
          "guilds",
          currentGuilds.filter((_, i) => i !== index),
          true
        )
        .then(() => {
          formik.validateField("guilds");
        });

      if (expandedAccordion === index) {
        setExpandedAccordion(0);
      } else if (expandedAccordion > index) {
        setExpandedAccordion(expandedAccordion - 1);
      }
    }
  };

  const handleConfirmDelete = () => {
    if (deleteDialogIndex === null) return;

    const guildToDelete = guildsList[deleteDialogIndex];
    if (!guildToDelete?.key) return;

    setIsDeletingGuild(true);
    dispatch(deactivateGuildService(guildToDelete.key)).then((r) => {
      setIsDeletingGuild(false);
      setDeleteDialogOpen(false);
      setDeleteDialogIndex(null);

      if (r.payload?.error) {
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: r.payload.error,
          severity: "error",
        });
      } else {
        openNotif({
          vertical: "top",
          horizontal: "center",
          msg: "صنف با موفقیت حذف شد",
          severity: "success",
        });
        // Remove from list after successful deletion
        if (guildsList.length > 1) {
          setGuildsList(guildsList.filter((_, i) => i !== deleteDialogIndex));
          setGuildsFormValues(
            guildsFormValues.filter((_, i) => i !== deleteDialogIndex)
          );

          // Remove from Formik's guilds array
          const currentGuilds = formik.values.guilds || [];
          formik
            .setFieldValue(
              "guilds",
              currentGuilds.filter((_, i) => i !== deleteDialogIndex),
              true
            )
            .then(() => {
              formik.validateField("guilds");
            });

          // If deleted accordion was expanded, expand the first one
          if (expandedAccordion === deleteDialogIndex) {
            setExpandedAccordion(0);
          } else if (expandedAccordion > deleteDialogIndex) {
            // Adjust expanded index if deleted item was before it
            setExpandedAccordion(expandedAccordion - 1);
          }
        }
        if (updateTable) {
          updateTable();
        }
      }
    });
  };

  const handleCloseDeleteDialog = () => {
    if (!isDeletingGuild) {
      setDeleteDialogOpen(false);
      setDeleteDialogIndex(null);
    }
  };

  const handleGuildValuesChange = useCallback(
    (index, fieldName, value) => {
      setGuildsFormValues((prev) => {
        const newValues = [...prev];
        if (!newValues[index]) {
          newValues[index] = getInitialValues(null);
        }
        newValues[index] = {
          ...newValues[index],
          [fieldName]: value,
        };
        return newValues;
      });

      // Sync validated guild fields to Formik's guilds array (schema: license_number, steward, guild)
      if (
        fieldName === "steward" ||
        fieldName === "guild" ||
        fieldName === "license_number"
      ) {
        const currentGuilds = formik.values.guilds || [];
        const updatedGuilds = [...currentGuilds];
        if (!updatedGuilds[index]) {
          updatedGuilds[index] = { steward: false, guild: false };
        }
        updatedGuilds[index] = {
          ...updatedGuilds[index],
          [fieldName]: value,
        };
        formik.setFieldValue("guilds", updatedGuilds, true).then(() => {
          formik.validateField("guilds");
        });
      }
    },
    [formik]
  );

  const handleAccordionChange = (index) => (event, isExpanded) => {
    setExpandedAccordion(isExpanded ? index : false);
  };

  const shouldShowUpdateButton =
    formik?.values?.national_id &&
    (isAdmin ||
      (dbRegister !== false &&
        (guild ||
          (!guild &&
            ((dbRegister === true && hasInquiry === false) ||
              (isAdmin && isInquiryDone))))));

  const shouldShowInquiryForm = !guild && !isInquiryDone;
  const shouldShowFormContent = guild || isInquiryDone;

  return (
    <form onSubmit={formik.handleSubmit}>
      <Grid
        container
        gap={SPACING.TINY}
        sx={{
          maxHeight: "80vh",
          overflow: "auto",
          p: 2,
          minWidth:
            !guild && !isInquiryDone
              ? "auto"
              : {
                  xs: "96vw",
                  md: "90vw",
                  nlg: "1280px",
                },
        }}
      >
        {shouldShowUpdateButton && (
          <UpdateFromExternalButton
            onUpdate={handleUpdateFromExternal}
            disabled={!!formik.errors.national_id}
          />
        )}

        {shouldShowInquiryForm && (
          <InquiryForm
            inquiryNationalCode={inquiryNationalCode}
            setInquiryNationalCode={setInquiryNationalCode}
            onInquiry={handleInquiry}
            isAdmin={isAdmin}
          />
        )}

        {shouldShowFormContent && (
          <>
            <Grid container xs={12}>
              <PersonalInfoSection
                formik={formik}
                guild={guild}
                hasInquiry={hasInquiry}
                isAdmin={isAdmin}
                isSuperAdmin={isSuperAdmin}
                isKillHouse={isKillHouse}
                cities={cities}
              />

              <Grid
                item
                xs={12}
                lg={6}
                pr={{ xs: 0, md: 2 }}
                pl={{ xs: 0, md: 3 }}
              >
                <Grid container gap={SPACING.TINY} direction="column">
                  <Grid item xs={12}>
                    <Typography variant="h6" gutterBottom>
                      اطلاعات واحد
                    </Typography>
                  </Grid>

                  <Grid item xs={12}>
                    {guildsList.map((guildItem, index) => (
                      <Box key={index} sx={{ mb: 2 }}>
                        <GuildInfoAccordionItem
                          guildIndex={index}
                          guildData={guildItem}
                          guildActive={guildActive}
                          isAdmin={isAdmin}
                          isSuperAdmin={isSuperAdmin}
                          cities={cities}
                          typeActivities={typeActivities}
                          onDelete={() => handleDeleteGuild(index)}
                          canDelete={
                            (guildsList.length > 1 || !guild) && isAdmin
                          }
                          guildFormValues={guildsFormValues[index]}
                          onGuildValuesChange={handleGuildValuesChange}
                          expanded={expandedAccordion === index}
                          onChange={handleAccordionChange(index)}
                          mainFormik={formik}
                        />
                      </Box>
                    ))}
                  </Grid>
                  {isAdmin && (
                    <Grid item xs={12} xl={4}>
                      <Button
                        variant="contained"
                        color="primary"
                        startIcon={<AddIcon />}
                        onClick={handleAddGuild}
                        fullWidth
                        sx={{ mb: 2 }}
                      >
                        {`افزودن واحد`}
                      </Button>
                    </Grid>
                  )}
                </Grid>
              </Grid>
            </Grid>
            <Grid container item xs={12}>
              {hasRegisterCode &&
                (!(!guild && hasInquiry === true) ||
                  isAdmin ||
                  isSuperAdmin ||
                  isKillHouse) && (
                  <ConfirmationDialog
                    isAccepted={formik.values.isAccepted}
                    onAccept={() => formik.setFieldValue("isAccepted", true)}
                    onReject={() => formik.setFieldValue("isAccepted", false)}
                  />
                )}

              <FormActions
                formik={formik}
                onClose={() => dispatch(CLOSE_MODAL())}
                guildsCount={guildsList.length}
                showCloseButton={
                  !guild &&
                  hasInquiry === true &&
                  !isAdmin &&
                  !isSuperAdmin &&
                  !isKillHouse
                }
                formData={guildsList.map((guildItem, index) => {
                  const guildValues = guildsFormValues[index];
                  const combinedValues = {
                    ...guildValues, // Guild-specific info (overrides if same keys exist)
                  };
                  return prepareSubmitData(
                    combinedValues,
                    guildItem,
                    originalPhoneNumber,
                    hasInquiry
                  );
                })}
                isKillHouse={isKillHouse}
                onSubmit={formik.handleSubmit}
              />
            </Grid>
          </>
        )}
      </Grid>
      <DeleteConfirmationDialog
        open={deleteDialogOpen}
        onClose={handleCloseDeleteDialog}
        onConfirm={handleConfirmDelete}
        isDeleting={isDeletingGuild}
      />
    </form>
  );
};
