/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";

import { ICity, IProvince } from "@/types/types";
import SelectBox from "@/components/elements/SelectBox";
import RoundedInput from "@/components/elements/RoundedInput";
import { useState, useEffect } from "react";
import useAxios from "@/hooks/useAxios";
import Map, { GeolocateControl, Marker } from "react-map-gl";
import "mapbox-gl/dist/mapbox-gl.css";
import Image from "next/image";
import { useTranslation } from "react-i18next";
import {
  PROJECT_FIELD_CLASS,
  PROJECT_FIELD_ERROR_CLASS,
} from "@/lib/projectFormStyles";

interface LocationSelectorProps {
  formik: any;
}

const LocationSelector: React.FC<LocationSelectorProps> = ({ formik }) => {
  const { t } = useTranslation("common");
  const { request } = useAxios();
  const [allStates, setAllStates] = useState<IProvince[] | null>(null);
  const [cities, setCities] = useState<ICity[] | null>(null);
  const [selectedLocation, setSelectedLocation] = useState<{
    lat: number;
    lng: number;
  } | null>(null);
  const [mapReady, setMapReady] = useState(false);

  useEffect(() => {
    setMapReady(true);
  }, []);

  const fetchStates = async () => {
    try {
      const response = await request<{ provinces: IProvince[] }>(
        "GET",
        "/provinces"
      );
      setAllStates(response?.provinces || null);
    } catch (err) {
      console.log(err);
    }
  };

  const fetchCities = async (provinceId: string) => {
    try {
      const response = await request<{ cities: ICity[] }>(
        "GET",
        `/cities/${provinceId}`
      );
      setCities(response?.cities || []);
    } catch (err) {
      console.log(err);
    }
  };

  useEffect(() => {
    fetchStates();
  }, []);

  useEffect(() => {
    if (formik.values.stateId) {
      fetchCities(formik.values.stateId);
    }
  }, [formik?.values?.stateId]);

  useEffect(() => {
    const coords = formik.values.markerCoordinate;
    if (Array.isArray(coords) && coords.length >= 2) {
      setSelectedLocation({
        lat: Number(coords[1]),
        lng: Number(coords[0]),
      });
    }
  }, [formik?.values?.markerCoordinate]);

  const handleProvinceChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const selectedProvinceId = e.target.value;
    formik.setFieldValue("stateId", selectedProvinceId);
    formik.setFieldValue("cityId", "");
    fetchCities(selectedProvinceId);
  };

  const handleMapClick = (event: any) => {
    const { lngLat } = event;
    setSelectedLocation({
      lat: lngLat.lat,
      lng: lngLat.lng,
    });
    formik.setFieldValue("markerCoordinate", [lngLat.lng, lngLat.lat]);
  };

  const selectClass = (touched?: boolean, error?: string) =>
    `max-w-full ${touched && error ? PROJECT_FIELD_ERROR_CLASS : PROJECT_FIELD_CLASS}`;

  return (
    <>
      <SelectBox
        className={selectClass(formik.touched.stateId, formik.errors.stateId)}
        value={formik.values.stateId}
        onChange={handleProvinceChange}
      >
        <option disabled value="">
          {t("filters.province")}
        </option>
        {allStates?.map((item: IProvince) => (
          <option key={item.id} value={item.id}>
            {item?.name}
          </option>
        ))}
      </SelectBox>
      {formik.touched.stateId && formik.errors.stateId && (
        <small className="block text-center text-red-500">
          {formik.errors.stateId}
        </small>
      )}

      <SelectBox
        className={selectClass(formik.touched.cityId, formik.errors.cityId)}
        value={formik.values.cityId}
        onChange={(e) => formik.setFieldValue("cityId", e.target.value)}
      >
        <option disabled value="">
          {t("filters.city")}
        </option>
        {cities?.map((city: ICity) => (
          <option key={city.id} value={city.id}>
            {city.name}
          </option>
        ))}
      </SelectBox>
      {formik.touched.cityId && formik.errors.cityId && (
        <small className="block text-center text-red-500">
          {formik.errors.cityId}
        </small>
      )}

      <div className="mt-2 w-full overflow-hidden rounded-2xl">
        {mapReady ? (
          <Map
            style={{ height: "240px" }}
            initialViewState={{
              longitude: selectedLocation?.lng || 51.375433528216654,
              latitude: selectedLocation?.lat || 35.73356434056531,
              zoom: 11,
            }}
            mapboxAccessToken="pk.eyJ1IjoiYWxkZjkyIiwiYSI6ImNscHh5ZG56dTByMXAycnJ2cDNmdDQ5M3YifQ.a_sUt1rLFMfA0jHrETcM7A"
            mapStyle="mapbox://styles/mapbox/streets-v11"
            onClick={handleMapClick}
          >
            <GeolocateControl />
            {selectedLocation && (
              <Marker
                latitude={selectedLocation.lat}
                longitude={selectedLocation.lng}
              >
                <Image
                  alt="location icon"
                  className="-mt-5"
                  width={25}
                  height={25}
                  src={"/images/icons/location.svg"}
                />
              </Marker>
            )}
          </Map>
        ) : (
          <div className="flex h-[240px] items-center justify-center bg-neutral-100 text-xs dark:bg-neutral-800">
            …
          </div>
        )}
        {formik.touched.markerCoordinate && formik.errors.markerCoordinate && (
          <p className="text-xs text-red-500">
            {formik.errors.markerCoordinate as string}
          </p>
        )}
      </div>

      <RoundedInput
        className={`mt-2 max-w-full text-xs ${PROJECT_FIELD_CLASS}`}
        type="text"
        placeholder={t("projects.newProject.fields.neighborhoodOptional")}
        {...formik.getFieldProps("neighborhood")}
      />

      <textarea
        className={`mt-2 h-24 w-full rounded-3xl bg-secondary-light p-4 font-medium dark:bg-secondary-dark ${PROJECT_FIELD_CLASS}`}
        placeholder={t("projects.newProject.fields.addressOptional")}
        {...formik.getFieldProps("address")}
      />
    </>
  );
};

export default LocationSelector;
