"use client";

import AuthPageLayout, {
  AuthFormFooter,
  AuthPageContent,
} from "@/components/auth/AuthPageLayout";
import AuthNextButton from "@/components/auth/AuthNextButton";
import LocalePageShell from "@/components/i18n/LocalePageShell";
import { IMAGE_BASE_URL } from "@/components/main/BaseUrl";
import BoldIcon from "@/components/ui/BoldIcon";
import useAxios from "@/hooks/useAxios";
import { useProductWizardId } from "@/hooks/useProductWizardId";
import { cn } from "@/lib/utils";
import Image from "next/image";
import { useParams, useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";

type PickedImage =
  | { type: "existing"; path: string }
  | { type: "new"; file: File; preview: string };

function imageSrc(img: PickedImage): string {
  return img.type === "existing" ? IMAGE_BASE_URL + img.path : img.preview;
}

function ProductImagesPage() {
  const { t } = useTranslation("common");
  const router = useRouter();
  const params = useParams<{ shopId: string }>();
  const shopId = params.shopId;
  const { request, loading } = useAxios();
  const listingId = useProductWizardId(shopId);

  const [images, setImages] = useState<PickedImage[]>([]);
  const [primaryIndex, setPrimaryIndex] = useState(0);

  useEffect(() => {
    if (!listingId) return;
    request<{ listing: { images: string[]; primaryImageIndex: number } }>(
      "GET",
      `/shop-products/${listingId}`
    ).then((res) => {
      if (!res?.listing) return;
      setImages((res.listing.images || []).map((path) => ({ type: "existing", path })));
      setPrimaryIndex(res.listing.primaryImageIndex || 0);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [listingId]);

  const handleSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(event.target.files || []);
    const picked: PickedImage[] = files.map((file) => ({
      type: "new",
      file,
      preview: URL.createObjectURL(file),
    }));
    setImages((prev) => [...prev, ...picked]);
  };

  const removeImage = (index: number) => {
    setImages((prev) => prev.filter((_, i) => i !== index));
    if (primaryIndex >= index && primaryIndex > 0) {
      setPrimaryIndex((prev) => prev - 1);
    }
  };

  const goNext = () => router.push(`/shops/${shopId}/products/new/variants`);

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

    const existingImages = images
      .filter((img): img is Extract<PickedImage, { type: "existing" }> => img.type === "existing")
      .map((img) => img.path);
    const newFiles = images.filter(
      (img): img is Extract<PickedImage, { type: "new" }> => img.type === "new"
    );

    const formData = new FormData();
    newFiles.forEach((img) => formData.append("images", img.file, img.file.name));
    formData.append("existing_images", JSON.stringify(existingImages));
    formData.append("primaryImageIndex", String(primaryIndex));

    try {
      await request("PATCH", `/shop-products/${listingId}`, formData);
      goNext();
    } catch (err: unknown) {
      const message =
        (err as { response?: { data?: { message?: string } } })?.response
          ?.data?.message || t("shops.unknownError");
      toast.error(message);
    }
  };

  if (!listingId) return null;

  return (
    <LocalePageShell>
      <AuthPageLayout>
        <AuthPageContent>
          <span className="text-xl font-bold mb-4">{t("shops.productImagesTitle")}</span>
          <p className="mb-4 text-xs text-neutral-500">
            {t("shops.productImagesHint")}
          </p>

          <div className="grid w-full max-w-sm grid-cols-3 gap-2">
            {images.map((img, index) => (
              <div
                key={img.type === "existing" ? img.path : img.preview}
                className={cn(
                  "relative aspect-square overflow-hidden rounded-3xl border-2",
                  primaryIndex === index
                    ? "border-pink-500"
                    : "border-neutral-200 dark:border-neutral-700"
                )}
              >
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={imageSrc(img)}
                  alt=""
                  className="h-full w-full object-cover"
                />
                <button
                  type="button"
                  onClick={() => setPrimaryIndex(index)}
                  className={cn(
                    "absolute bottom-1 right-1 rounded-full px-2 py-0.5 text-[10px] font-bold",
                    primaryIndex === index
                      ? "bg-pink-500 text-white"
                      : "bg-black/50 text-white"
                  )}
                >
                  {primaryIndex === index
                    ? t("shops.primaryImage")
                    : t("shops.setPrimaryImage")}
                </button>
                <button
                  type="button"
                  onClick={() => removeImage(index)}
                  aria-label={t("shops.removeImage")}
                  className="absolute top-1 left-1 rounded-full bg-black/50 p-1"
                >
                  <BoldIcon name="close-circle" size={16} tinted className="text-white" />
                </button>
              </div>
            ))}

            <label
              htmlFor="productImagesInput"
              className="flex aspect-square cursor-pointer items-center justify-center rounded-3xl border-2 border-dashed border-neutral-300 dark:border-neutral-600"
            >
              <Image
                src="/images/icons/gallery-add.svg"
                width={36}
                height={36}
                alt=""
                className="dark:brightness-0 dark:invert"
              />
            </label>
            <input
              id="productImagesInput"
              type="file"
              accept="image/*"
              multiple
              className="hidden"
              onChange={handleSelect}
            />
          </div>
        </AuthPageContent>
        <AuthFormFooter onSkip={goNext} skipDisabled={loading}>
          <AuthNextButton
            type="button"
            loading={loading}
            disabled={loading}
            onClick={handleSubmit}
          >
            {t("shops.saveAndContinue")}
          </AuthNextButton>
        </AuthFormFooter>
      </AuthPageLayout>
    </LocalePageShell>
  );
}

export default ProductImagesPage;
