"use client";

import AuthPageLayout, {
  AuthFormFooter,
  AuthPageContent,
} from "@/components/auth/AuthPageLayout";
import AuthNextButton from "@/components/auth/AuthNextButton";
import RoundedInput from "@/components/elements/RoundedInput";
import SelectBox from "@/components/elements/SelectBox";
import LocalePageShell from "@/components/i18n/LocalePageShell";
import useAxios from "@/hooks/useAxios";
import { useShopWizardId } from "@/hooks/useShopWizardId";
import { ICity, IProvince } from "@/types/types";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import Map, { GeolocateControl, MapMouseEvent, Marker } from "react-map-gl";
import "mapbox-gl/dist/mapbox-gl.css";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";

function ShopLocationPage() {
  const { t } = useTranslation("common");
  const router = useRouter();
  const { request, loading } = useAxios();
  const shopId = useShopWizardId();

  const [hasPhysicalLocation, setHasPhysicalLocation] = useState(true);
  const [provinces, setProvinces] = useState<IProvince[] | null>(null);
  const [cities, setCities] = useState<ICity[] | null>(null);
  const [provinceId, setProvinceId] = useState("");
  const [cityId, setCityId] = useState("");
  const [neighbourhood, setNeighbourhood] = useState("");
  const [address, setAddress] = useState("");
  const [marker, setMarker] = useState<{ lat: number; lng: number } | null>(
    null
  );

  useEffect(() => {
    request<{ provinces: IProvince[] }>("GET", "/provinces")
      .then((res) => setProvinces(res?.provinces || []))
      .catch(() => setProvinces([]));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (!shopId) return;
    request<{
      shop: {
        has_physical_location?: boolean;
        province?: IProvince | null;
        city?: ICity | null;
        neighbourhood?: string | null;
        address?: string | null;
        lat?: string | null;
        lng?: string | null;
      };
    }>("GET", `/shops/${shopId}`).then((res) => {
      const shop = res?.shop;
      if (!shop) return;
      setHasPhysicalLocation(shop.has_physical_location ?? true);
      if (shop.province) {
        setProvinceId(String(shop.province.id));
        request<{ cities: ICity[] }>("GET", `/cities/${shop.province.id}`)
          .then((r) => setCities(r?.cities || []))
          .catch(() => setCities([]));
      }
      if (shop.city) setCityId(String(shop.city.id));
      if (shop.neighbourhood) setNeighbourhood(shop.neighbourhood);
      if (shop.address) setAddress(shop.address);
      if (shop.lat && shop.lng) {
        setMarker({ lat: Number(shop.lat), lng: Number(shop.lng) });
      }
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [shopId]);

  const handleProvinceChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const id = e.target.value;
    setProvinceId(id);
    setCityId("");
    request<{ cities: ICity[] }>("GET", `/cities/${id}`)
      .then((res) => setCities(res?.cities || []))
      .catch(() => setCities([]));
  };

  const handleMapClick = (event: MapMouseEvent) => {
    setMarker({ lat: event.lngLat.lat, lng: event.lngLat.lng });
  };

  const handleSubmit = async () => {
    if (!shopId) return;

    const province = provinces?.find((p) => String(p.id) === provinceId) || null;
    const city = cities?.find((c) => String(c.id) === cityId) || null;

    if (!province) {
      toast.error(t("shops.provinceRequired"));
      return;
    }
    if (!city) {
      toast.error(t("shops.cityRequired"));
      return;
    }

    try {
      await request("PATCH", `/shops/${shopId}/location`, {
        has_physical_location: hasPhysicalLocation,
        province,
        city,
        neighbourhood,
        address,
        lat: marker?.lat != null ? String(marker.lat) : null,
        lng: marker?.lng != null ? String(marker.lng) : null,
      });
      router.push("/shops/new/contact");
    } catch (err: unknown) {
      const message =
        (err as { response?: { data?: { message?: string } } })?.response
          ?.data?.message || t("shops.unknownError");
      toast.error(message);
    }
  };

  if (!shopId) return null;

  return (
    <LocalePageShell>
      <AuthPageLayout>
        <AuthPageContent>
          <span className="text-xl font-bold mb-4">{t("shops.locationTitle")}</span>

          <div className="flex w-full max-w-sm flex-col gap-2">
            <label className="mb-2 flex items-center gap-2">
              <input
                type="checkbox"
                className="scale-125"
                checked={!hasPhysicalLocation}
                onChange={() => setHasPhysicalLocation((v) => !v)}
              />
              <span className="text-sm">{t("shops.noPhysicalShop")}</span>
            </label>

            <SelectBox value={provinceId} onChange={handleProvinceChange}>
                  <option disabled value="">
                    {t("filters.province")}
                  </option>
                  {provinces?.map((p) => (
                    <option key={p.id} value={p.id}>
                      {p.name}
                    </option>
                  ))}
                </SelectBox>

                <SelectBox
                  value={cityId}
                  onChange={(e) => setCityId(e.target.value)}
                >
                  <option disabled value="">
                    {t("filters.city")}
                  </option>
                  {cities?.map((c) => (
                    <option key={c.id} value={c.id}>
                      {c.name}
                    </option>
                  ))}
                </SelectBox>

                <div className="mt-2 w-full overflow-hidden rounded-2xl">
                  <Map
                    style={{ height: "220px" }}
                    initialViewState={{
                      longitude: marker?.lng || 51.375433528216654,
                      latitude: marker?.lat || 35.73356434056531,
                      zoom: 11,
                    }}
                    mapboxAccessToken="pk.eyJ1IjoiYWxkZjkyIiwiYSI6ImNscHh5ZG56dTByMXAycnJ2cDNmdDQ5M3YifQ.a_sUt1rLFMfA0jHrETcM7A"
                    mapStyle="mapbox://styles/mapbox/streets-v11"
                    onClick={handleMapClick}
                  >
                    <GeolocateControl />
                    {marker && (
                      <Marker latitude={marker.lat} longitude={marker.lng}>
                        <Image
                          alt="location icon"
                          className="-mt-5"
                          width={25}
                          height={25}
                          src="/images/icons/location.svg"
                        />
                      </Marker>
                    )}
                  </Map>
                </div>

                <RoundedInput
                  type="text"
                  className="mt-2 text-xs"
                  placeholder={t("shops.neighbourhoodPlaceholder")}
                  value={neighbourhood}
                  onChange={(e) => setNeighbourhood(e.target.value)}
                />
                <textarea
                  className="mt-2 h-24 w-full rounded-3xl border border-neutral-950 bg-white p-4 font-medium dark:border-neutral-400 dark:bg-neutral-950 dark:text-neutral-50"
                  placeholder={t("shops.addressPlaceholder")}
                  value={address}
                  onChange={(e) => setAddress(e.target.value)}
                />
          </div>
        </AuthPageContent>
        <AuthFormFooter>
          <AuthNextButton
            type="button"
            loading={loading}
            disabled={loading}
            onClick={handleSubmit}
          >
            {t("shops.saveAndContinue")}
          </AuthNextButton>
        </AuthFormFooter>
      </AuthPageLayout>
    </LocalePageShell>
  );
}

export default ShopLocationPage;
