import { Autocomplete, Box, TextField } from "@mui/material";
import { Create, useAutocomplete } from "@refinedev/mui";
import { useForm } from "@refinedev/react-hook-form";
import { Controller } from "react-hook-form";
import { useEffect, useState } from "react";
import { EVERY_LANGUAGE, Languages, languageStore } from "@stores"; // Assuming these imports are correct and available
import { LanguageSwitch } from "@/components/LanguageSwitch"; // Assuming this import is correct and available
import { axiosInstance, axiosInstanceForGet } from "@/providers"; // Assuming these imports are correct and available
import { useNavigate } from "react-router";
import { useNotification } from "@refinedev/core";

export const CityCreate = () => {
  const { language, setLanguageAction } = languageStore;
  const navigate = useNavigate();
  const notification = useNotification();
  // State to hold all language translations for the city name.
  // Initialized with an object where each language key maps to an empty string.
  const [allLanguageNames, setAllLanguageNames] = useState<
    Record<Languages, string>
  >(EVERY_LANGUAGE(""));

  const {
    saveButtonProps,
    refineCore: { formLoading }, // Indicates if the form is currently loading data
    register, // Function to register input fields with react-hook-form
    control, // Object to pass to Controller for controlled components
    setValue, // Function to programmatically set form values
    watch, // Function to watch for changes in form values
    handleSubmit, // Function to handle form submission, including validation
    formState: { errors }, // Object containing form validation errors
  } = useForm<{
    name: string; // This field will hold the name for the *currently active* language
    country_code: string; // The code for the selected country
    arms: string; // The ID of the selected media for the city's arms (e.g., coat of arms)
  }>({});

  // useEffect hook to synchronize the 'name' TextField with the 'allLanguageNames' state.
  // Whenever the active 'language' or the 'allLanguageNames' state changes,
  // the 'name' field in the form is updated to display the correct translation.
  useEffect(() => {
    setValue("name", allLanguageNames[language]);
  }, [language, allLanguageNames, setValue]);

  // Function to update the 'allLanguageNames' state with the current value from the 'name' TextField.
  // This is crucial to ensure that changes made by the user are saved before
  // switching languages or submitting the form.
  const updateCurrentLanguageName = () => {
    const currentNameValue = watch("name"); // Get the current value typed into the 'name' TextField
    setAllLanguageNames((prev) => ({
      ...prev,
      [language]: currentNameValue || "", // Update the specific language entry in the state
    }));
  };

  // Handler for language switch.
  // It first saves the current input for the active language, then changes the language.
  const handleLanguageChange = (lang: Languages) => {
    updateCurrentLanguageName(); // Save the current input before switching language
    setLanguageAction(lang); // Update the global language state
  };

  // Autocomplete props for Country selection.
  // 'resource' specifies the API endpoint, and it's assumed 'code' is the value
  // to be stored and 'name' is the label to display.
  const { autocompleteProps: countryAutocompleteProps } = useAutocomplete({
    resource: "country",
  });

  // Autocomplete props for Media selection (specifically for city's arms).
  // 'resource' specifies the API endpoint, and 'onSearch' provides a custom
  // search filter based on 'media_name'.
  const { autocompleteProps: mediaAutocompleteProps } = useAutocomplete({
    resource: "media",
    onSearch: (value) => [
      {
        field: "media_name",
        operator: "contains",
        value,
      },
    ],
  });

  // This function is called when the form is submitted and passes validation.
  // It orchestrates the API calls for creating the city and updating its translations.
  const onFinish = async (data: {
    name: string;
    country_code: string;
    arms: string;
  }) => {
    // Ensure the very latest input for the current language is captured
    // into 'allLanguageNames' before making API calls. This handles cases
    // where the user might click 'Save' without blurring the 'name' field.
    updateCurrentLanguageName();

    // Create a final set of names including the latest value from the form
    // for the current language.
    const finalNames = {
      ...allLanguageNames,
      [language]: data.name, // Ensure the absolute latest value from the form is included
    };

    try {
      // Validate that the Russian name is present, as it's used for the initial POST request.
      if (!finalNames["ru"]) {
        console.error("Russian name is required for initial city creation.");
        // In a real application, you might want to display a user-friendly error message here.
        return;
      }

      console.log("Submitting with names:", finalNames);

      // 1. Create the city entry in Russian.
      // This POST request typically returns the ID of the newly created resource.
      const ruResponse = await axiosInstanceForGet("ru").post("/city", {
        name: finalNames["ru"], // Russian name
        country_code: data.country_code, // Country code from the form
        arms: data.arms, // Arms ID from the form, included in initial creation
      });

      const id = ruResponse.data.id; // Extract the ID of the newly created city

      // 2. Patch the city with the English name if available.
      if (finalNames["en"]) {
        await axiosInstanceForGet("en").patch(`/city/${id}`, {
          name: finalNames["en"], // English name
          country_code: data.country_code, // Country code from the form
          arms: data.arms, // Arms ID from the form, included in initial creation
        });
      }

      // 3. Patch the city with the Chinese name if available.
      if (finalNames["zh"]) {
        await axiosInstanceForGet("zh").patch(`/city/${id}`, {
          name: finalNames["zh"], // Chinese name
          country_code: data.country_code, // Country code from the form
          arms: data.arms, // Arms ID from the form, included in initial creation
        });
      }

      console.log("City created/updated successfully!");
      if (notification && typeof notification.open === "function") {
        notification.open({
          message: "Город успешно создан",
          type: "success",
        });
      }
      window.onbeforeunload = null;
      navigate("/city");

      // After successful creation/update, you might want to:
      // - Navigate to a different page (e.g., city list).
      // - Display a success notification to the user.
    } catch (error) {
      console.error("Error creating/updating city:", error);
      // Display an error message to the user if the API calls fail.
    }
  };

  return (
    <Create
      isLoading={formLoading} // Show loading indicator if form data is being fetched
      // Pass the handleSubmit function to the save button's onClick.
      // This ensures form validation runs before 'onFinish' is called.
      saveButtonProps={{
        ...saveButtonProps,
        onClick: handleSubmit(onFinish as any),
      }}
    >
      <Box
        component="form"
        sx={{ display: "flex", flexDirection: "column" }}
        autoComplete="off" // Disable browser autocomplete
      >
        {/* Language Switch component to change the active language */}
        <LanguageSwitch action={handleLanguageChange} />

        {/* Country Autocomplete field */}
        <Controller
          control={control} // Pass control from useForm
          name="country_code" // Field name in the form state
          rules={{ required: "Это поле является обязательным" }} // Validation rule
          defaultValue={null} // Initial value
          render={({ field }) => (
            <Autocomplete
              {...countryAutocompleteProps} // Spread autocomplete props from useAutocomplete hook
              value={
                // Find the selected option based on the field's current value
                countryAutocompleteProps.options.find(
                  (option: { code: string; name: string; id: string }) =>
                    option.code === field.value
                ) || null
              }
              onChange={(
                _,
                value: { code: string; name: string; id: string } | null
              ) => {
                // Update the form field's value when an option is selected
                field.onChange(value?.code || "");
              }}
              getOptionLabel={(item: {
                code: string;
                name: string;
                id: string;
              }) => {
                // Define how to display the label for each option
                return item ? item.name : "";
              }}
              isOptionEqualToValue={(
                option: { code: string; name: string; id: string },
                value: { code: string; name: string; id: string }
              ) => {
                // Define how to compare options for equality
                return option.id === value?.id;
              }}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="Выберите страну"
                  margin="normal"
                  variant="outlined"
                  error={!!errors.country_code} // Show error state if validation fails
                  required // Mark as required in UI
                />
              )}
            />
          )}
        />

        {/* City Name TextField for the current language */}
        <TextField
          {...register("name", {
            required: "Это поле является обязательным", // Validation rule
            onBlur: updateCurrentLanguageName, // Update translations when the field loses focus
          })}
          error={!!errors.name} // Show error state if validation fails
          margin="normal"
          fullWidth
          InputLabelProps={{ shrink: true }}
          type="text"
          label={"Название *"}
          name="name" // HTML name attribute, matches register key
        />

        {/* Arms Autocomplete field */}
        <Controller
          control={control} // Pass control from useForm
          name="arms" // Field name in the form state
          defaultValue={null} // Initial value
          render={({ field }) => (
            <Autocomplete
              {...mediaAutocompleteProps} // Spread autocomplete props from useAutocomplete hook
              value={
                // Find the selected option based on the field's current value
                mediaAutocompleteProps.options.find(
                  (option: { id: string; media_name: string }) =>
                    option.id === field.value
                ) || null
              }
              onChange={(
                _,
                value: { id: string; media_name: string } | null
              ) => {
                // Update the form field's value when an option is selected
                field.onChange(value?.id || "");
              }}
              getOptionLabel={(item: { id: string; media_name: string }) => {
                // Define how to display the label for each option
                return item ? item.media_name : "";
              }}
              isOptionEqualToValue={(
                option: { id: string; media_name: string },
                value: { id: string; media_name: string }
              ) => {
                // Define how to compare options for equality
                return option.id === value?.id;
              }}
              filterOptions={(
                options: { id: string; media_name: string }[],
                { inputValue }
              ) => {
                // Custom filter for options based on input value
                return options.filter((option) =>
                  option.media_name
                    .toLowerCase()
                    .includes(inputValue.toLowerCase())
                );
              }}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="Выберите герб"
                  margin="normal"
                  variant="outlined"
                  error={!!errors.arms} // Show error state if validation fails
                />
              )}
            />
          )}
        />
      </Box>
    </Create>
  );
};
