"use client";

import * as Yup from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { useMemo, useEffect, useCallback } from "react";
import Card from "@mui/material/Card";
import Grid from "@mui/material/Unstable_Grid2";
import LoadingButton from "@mui/lab/LoadingButton";
import { paths } from "@/routes/paths";
import { useRouter, useResponsive } from "@/hooks";
import { useSnackbar } from "@/components/snackbar";
import FormProvider, {
  RHFEditor,
  RHFSelect,
  RHFTextField,
  RHFUploadAvatar,
} from "@/shared/components/hook-form";
import RHFAutocomplete from "@/shared/components/hook-form/rhf-autocomplete";
import { Box, MenuItem, Stack, Typography } from "@mui/material";
import currencies from "@/shared/_mock/_devise/Common-Currency.json";
import { countries } from "@/shared/assets/data";
import { fData } from "@/utils/format-number";
import axiosInstancee from "@/utils/axios";
import { IAgency } from "@/shared/types/agency";

type Props = {
  currentAgency?: IAgency; // Optional prop to indicate edit mode
};

// Add a proper interface for your form values
interface AgencyFormValues {
  name: string;
  primaryAddresse: string;
  optionalAddress?: string;
  city: string;
  country: string;
  postalCode: string;
  description?: string;
  email: string;
  phoneNumber: string;
  createDate?: Date;
  currency: string;
  picture?: any; // Add this to support the picture property
}

export default function AgencyEditForm({ currentAgency }: Props) {
  const router = useRouter();
  const mdUp = useResponsive("up", "md");
  const { enqueueSnackbar } = useSnackbar();
  const date = new Date();

  // Define validation schema
  const NewAgencySchema = Yup.object().shape({
    name: Yup.string()
      .required("Name is required")
      .min(3, "Name must be at least 3 characters")
      .max(50, "Name must not exceed 50 characters")
      .matches(/^[a-zA-Z0-9\s-]+$/, "Name can only contain letters, numbers, spaces and hyphens"),

    email: Yup.string()
      .required("Email is required")
      .email("Email must be a valid email address")
      .matches(
        /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/,
        "Invalid email format"
      ),

    phoneNumber: Yup.string()
      .required("Phone number is required")
      .matches(
        /^[0-9]{10}$/,
        "Phone number must consist of exactly 10 digits"
      ),

    primaryAddresse: Yup.string()
      .required("Primary address is required")
      .min(5, "Address must be at least 5 characters")
      .max(100, "Address must not exceed 100 characters"),

    optionalAddress: Yup.string()
      .max(100, "Optional address must not exceed 100 characters"),

    description: Yup.string()
      .max(500, "Description must not exceed 500 characters"),

    currency: Yup.string()
      .required("Currency is required"),

    country: Yup.string()
      .required("Country is required"),

    city: Yup.string()
      .required("City is required")
      .min(2, "City must be at least 2 characters"),

    postalCode: Yup.string()
      .required("Postal code is required")
      .matches(/^[0-9]{4,6}$/, "Invalid postal code format"),
  });

  // Set up default values based on edit or create mode
  const defaultValues = useMemo(
    () => ({
      name: currentAgency?.name || "",
      primaryAddresse: currentAgency?.address?.primaryAddresse || "",
      optionalAddress: currentAgency?.address?.optionalAddress || "",
      city: currentAgency?.address?.city || "",
      country: currentAgency?.address?.country || "",
      postalCode: currentAgency?.address?.postalCode || "",
      description: currentAgency?.description || "",
      email: currentAgency?.email || "",
      phoneNumber: currentAgency?.phoneNumber || "",
      createDate: currentAgency?.createDate || date,
      currency: currentAgency?.currency || "",
      picture: currentAgency?.picture || null,
    }),
    [currentAgency]
  );

  // Then use this type with useForm
  const methods = useForm<AgencyFormValues>({
    resolver: yupResolver(NewAgencySchema),
    defaultValues,
    mode: 'onChange',
  });

  const {
    reset,
    setValue,
    handleSubmit,
    formState: { errors, isSubmitting, isDirty, isValid },
  } = methods;

  // Now reset will work with picture property
  useEffect(() => {
    if (currentAgency) {
      reset({
        ...defaultValues,
        picture: currentAgency.picture || null,
      });

      if (currentAgency.picture) {
        setValue("picture", {
          preview: currentAgency.picture,
        });
      }
    }
  }, [currentAgency, defaultValues, reset, setValue]);

  const onSubmit = handleSubmit(async (data) => {
    try {
      const formData = new FormData();
      // Only validate picture if it exists
      if (data.picture?.file) {
        if (data.picture.file.size > 3145728) {
          enqueueSnackbar('Image size must not exceed 3MB', { variant: 'error' });
          return;
        }
      }

      // Ensure phone number is exactly 10 digits
      const formattedPhone = data.phoneNumber.replace(/\D/g, '');
      if (formattedPhone.length !== 10) {
        enqueueSnackbar('Phone number must consist of exactly 10 digits', { variant: 'error' });
        return;
      }

      const agencyData = {
        // Make picture truly optional
        // Don't include picture in the JSON data at all
        name: data.name.trim(),
        email: data.email.toLowerCase(),
        phoneNumber: formattedPhone,
        description: data.description?.trim(),
        currency: data.currency,
        address: {
          primaryAddresse: data.primaryAddresse.trim(),
          optionalAddress: data.optionalAddress?.trim(),
          city: data.city.trim(),
          country: data.country,
          postalCode: data.postalCode,
        },
      };

      formData.append(
        "agency",
        new Blob([JSON.stringify(agencyData)], { type: "application/json" })
      );

      // Only append picture if it exists
      if (data.picture?.file || (data.picture instanceof File)) {
        formData.append("picture", data.picture.file || data.picture);
      }

      const apiUrl = currentAgency
        ? `/api/user/update/${currentAgency.id}`
        : "/api/user/api/v1/agency";

      const requestMethod = currentAgency ? axiosInstancee.put : axiosInstancee.post;

      await requestMethod(apiUrl, formData, {
        headers: { "Content-Type": "multipart/form-data" },
      });

      enqueueSnackbar(
        currentAgency
          ? "Agency updated successfully!"
          : "The agency is currently in validation!"
      );

      router.replace(paths.dashboard.agency.list);
    } catch (error: any) {
      console.error("Failed to create or update the agency:", error);

      if (error.response?.data?.message?.includes('phone number')) {
        enqueueSnackbar('Phone number must consist of exactly 10 digits', { variant: 'error' });
      } else {
        enqueueSnackbar(
          error.response?.data?.message || "Failed to create or update the agency",
          { variant: "error" }
        );
      }
    }
  });

  // File handler for picture upload
  const handleDrop = useCallback(
    (acceptedFiles: File[]) => {
      const file = acceptedFiles[0];
      const newFile = Object.assign(file, {
        preview: URL.createObjectURL(file), // Generate preview for new file
      });
      setValue("picture", newFile, { shouldValidate: true });
    },
    [setValue]
  );

  // Render form fields and action buttons
  return (
    <FormProvider methods={methods} onSubmit={onSubmit}>
      <Grid container spacing={3} sx={{ justifyContent: "center" }}>
        <Grid xs={12} md={4}>
          <Card sx={{ pt: 10, pb: 5, px: 3 }}>
            <Box sx={{ mb: 5 }}>
              <RHFUploadAvatar
                name="picture"
                maxSize={3145728}
                onDrop={handleDrop}
                helperText={
                  <Typography
                    variant="caption"
                    sx={{
                      mt: 3,
                      mx: "auto",
                      display: "block",
                      textAlign: "center",
                      color: "text.disabled",
                    }}
                  >
                    Optional: Upload agency logo<br />
                    Allowed *.jpeg, *.jpg, *.png, *.gif<br />
                    max size of {fData(3145728)}
                  </Typography>
                }
                value={methods.watch("picture")}
              />
            </Box>
            <Typography variant="subtitle2" sx={{ mb: 0.5 }}>
              Agency Logo
            </Typography>
          </Card>
        </Grid>

        <Grid xs={12} md={8}>
          <Card sx={{ p: 3 }}>
            <Box
              rowGap={3}
              columnGap={2}
              display="grid"
              gridTemplateColumns={{
                xs: "repeat(1, 1fr)",
                sm: "repeat(2, 1fr)",
              }}
            >
              <RHFTextField name="name" label="Agency Name" />
              <RHFSelect name="currency" label="Currency">
                <MenuItem value="" disabled>
                  Select Currency
                </MenuItem>
                {Object.entries(currencies).map(([code, { name, symbol }]) => (
                  <MenuItem
                    key={code}
                    value={code}
                  >{`${name} (${symbol})`}</MenuItem>
                ))}
              </RHFSelect>
              <RHFTextField name="phoneNumber" label="Phone Number" />
              <RHFTextField name="email" label="Email" type="email" />
              <RHFTextField name="primaryAddresse" label="Address" />
              <RHFTextField name="optionalAddress" label="Optional Address" />
              <RHFAutocomplete
                name="country"
                label="Country"
                options={countries.map((option) => option.label)}
              />
              <RHFTextField name="city" label="City" />
              <RHFTextField name="postalCode" label="Postal Code" />
            </Box>

            <Stack spacing={1} sx={{ pt: 2 }}>
              <RHFEditor
                simple
                name="description"
                placeholder="Description ..."
              />
            </Stack>
          </Card>
        </Grid>
      </Grid>

      {/* Button positioned at bottom right */}
      <Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 3 }}>
        <LoadingButton
          type="submit"
          variant="contained"
          size="large"
          loading={isSubmitting}
        >
          {!currentAgency ? "Create Agency" : "Save Changes"}
        </LoadingButton>
      </Box>
    </FormProvider>
  );
}
