"use client";

import Container from "@/components/elements/Container";
import LocalePageShell from "@/components/i18n/LocalePageShell";
import Header from "@/components/main/Header";
import { IMAGE_BASE_URL, staticIconUrl } from "@/components/main/BaseUrl";
import BoldIcon from "@/components/ui/BoldIcon";
import TabNavigation from "@/components/TabNavigation";
import useAxios from "@/hooks/useAxios";
import { saveProductWizardId } from "@/hooks/useProductWizardId";
import { cn } from "@/lib/utils";
import { IShopProductListing, IShopProductVariant } from "@/types/types";
import { useQueryClient } from "@tanstack/react-query";
import Image from "next/image";
import { useParams, useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";

type ShopHeader = { _id: string; name: string; logo?: string | null };

function uniqueValues(values: (string | null | undefined)[]): string[] {
  return Array.from(new Set(values.filter((v): v is string => Boolean(v))));
}

function SpecRow({
  label,
  children,
}: {
  label: string;
  children: React.ReactNode;
}) {
  return (
    <div className="flex w-full items-center gap-2 rounded-3xl border border-neutral-200 px-4 py-3 dark:border-neutral-700">
      <span className="shrink-0 text-sm font-bold">{label}</span>
      <div className="flex flex-1 flex-wrap items-center justify-end gap-2 text-right">
        {children}
      </div>
      <BoldIcon name="arrow-down" size={16} tinted className="shrink-0 text-neutral-400" />
    </div>
  );
}

export default function ProductManagePage() {
  const { t } = useTranslation("common");
  const router = useRouter();
  const params = useParams<{ shopId: string; listingId: string }>();
  const { shopId, listingId } = params;
  const { request } = useAxios();
  const queryClient = useQueryClient();

  const [listing, setListing] = useState<IShopProductListing | null>(null);
  const [selectedColor, setSelectedColor] = useState<string | null>(null);
  const [selectedSize, setSelectedSize] = useState<string | null>(null);
  const [selectedWeight, setSelectedWeight] = useState<string | null>(null);
  const [savingStock, setSavingStock] = useState(false);
  const [savingStatus, setSavingStatus] = useState(false);
  const [activeImageIndex, setActiveImageIndex] = useState(0);
  const [descriptionExpanded, setDescriptionExpanded] = useState(false);

  useEffect(() => {
    request<{ listing: IShopProductListing }>("GET", `/shop-products/${listingId}`)
      .then((res) => {
        const data = res?.listing || null;
        setListing(data);
        const firstVariant = data?.variants?.[0];
        if (firstVariant) {
          setSelectedColor(firstVariant.color || null);
          setSelectedSize(firstVariant.size || null);
          setSelectedWeight(firstVariant.weight || null);
        }
      })
      .catch(() => setListing(null));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [listingId]);

  const shopInfo: ShopHeader | null =
    listing && typeof listing.shop === "object" ? (listing.shop as ShopHeader) : null;

  const colors = useMemo(
    () => uniqueValues(listing?.variants.map((v) => v.color) || []),
    [listing]
  );

  /** Sizes narrow down to whichever color is currently selected. */
  const sizes = useMemo(() => {
    if (!listing) return [];
    const relevant = listing.variants.filter(
      (v) => colors.length === 0 || v.color === selectedColor
    );
    return uniqueValues(relevant.map((v) => v.size));
  }, [listing, colors, selectedColor]);

  /** Weights narrow down to whichever color + size are currently selected. */
  const weights = useMemo(() => {
    if (!listing) return [];
    const relevant = listing.variants.filter(
      (v) =>
        (colors.length === 0 || v.color === selectedColor) &&
        (sizes.length === 0 || v.size === selectedSize)
    );
    return uniqueValues(relevant.map((v) => v.weight));
  }, [listing, colors, sizes, selectedColor, selectedSize]);

  // Keep size/weight selections valid as the color (and then size) selection narrows them down.
  useEffect(() => {
    if (sizes.length > 0 && (!selectedSize || !sizes.includes(selectedSize))) {
      setSelectedSize(sizes[0]);
    }
  }, [sizes, selectedSize]);

  useEffect(() => {
    if (weights.length > 0 && (!selectedWeight || !weights.includes(selectedWeight))) {
      setSelectedWeight(weights[0]);
    }
  }, [weights, selectedWeight]);

  const matchedVariant: IShopProductVariant | null = useMemo(() => {
    if (!listing) return null;
    return (
      listing.variants.find(
        (v) =>
          (colors.length === 0 || v.color === selectedColor) &&
          (sizes.length === 0 || v.size === selectedSize) &&
          (weights.length === 0 || v.weight === selectedWeight)
      ) ||
      listing.variants[0] ||
      null
    );
  }, [listing, colors, sizes, weights, selectedColor, selectedSize, selectedWeight]);

  const categoryLine = listing
    ? [listing.category, listing.sub_category, listing.sub_sub_category]
        .filter(Boolean)
        .join(" / ")
    : "";

  const discountPercent =
    matchedVariant?.discount_price && matchedVariant.discount_price < matchedVariant.price
      ? Math.round(
          ((matchedVariant.price - matchedVariant.discount_price) / matchedVariant.price) * 100
        )
      : null;

  const adjustStock = async (delta: number) => {
    if (!listing || !matchedVariant || savingStock) return;
    const nextStock = Math.max(0, matchedVariant.stock + delta);
    const updatedVariants = listing.variants.map((v) =>
      v._id === matchedVariant._id ? { ...v, stock: nextStock } : v
    );

    setSavingStock(true);
    try {
      await request("PATCH", `/shop-products/${listing._id}`, {
        variants: updatedVariants.map((v) => ({
          color: v.color,
          size: v.size,
          weight: v.weight,
          price: v.price,
          discount_price: v.discount_price,
          stock: v._id === matchedVariant._id ? nextStock : v.stock,
          sku: v.sku,
        })),
      });
      setListing({ ...listing, variants: updatedVariants });
      queryClient.invalidateQueries({ queryKey: ["shop-products", shopId] });
    } catch {
      toast.error(t("shops.unknownError"));
    } finally {
      setSavingStock(false);
    }
  };

  const toggleActive = async () => {
    if (!listing || savingStatus) return;
    const nextStatus = listing.status === "inactive" ? "active" : "inactive";
    setSavingStatus(true);
    try {
      await request("PATCH", `/shop-products/${listing._id}`, { status: nextStatus });
      setListing({ ...listing, status: nextStatus });
      queryClient.invalidateQueries({ queryKey: ["shop-products", shopId] });
      toast.success(
        nextStatus === "inactive" ? t("shops.productDeactivated") : t("shops.productActivated")
      );
    } catch {
      toast.error(t("shops.unknownError"));
    } finally {
      setSavingStatus(false);
    }
  };

  const handleEdit = () => {
    if (!listing) return;
    saveProductWizardId(shopId, listing._id);
    router.push(`/shops/${shopId}/products/new/name?edit=1`);
  };

  if (!listing) return null;

  const images = listing.images || [];
  const isInactive = listing.status === "inactive";

  const handleImageScroll = (event: React.UIEvent<HTMLDivElement>) => {
    const el = event.currentTarget;
    const index = Math.round(el.scrollLeft / el.clientWidth);
    setActiveImageIndex(index);
  };

  return (
    <>
      <Header />
      <LocalePageShell>
      <Container className="pb-28">
        <div className="flex items-center justify-end gap-2">
          <span className="text-sm font-bold">{shopInfo?.name}</span>
          <span className="flex h-9 w-9 shrink-0 items-center justify-center overflow-hidden rounded-full bg-neutral-100 dark:bg-neutral-800">
            {shopInfo?.logo ? (
              // eslint-disable-next-line @next/next/no-img-element
              <img
                src={IMAGE_BASE_URL + shopInfo.logo}
                alt={shopInfo.name}
                className="h-full w-full object-cover"
              />
            ) : (
              <Image
                src={staticIconUrl("/images/icons/vuesax/bold/shop.svg")}
                width={18}
                height={18}
                alt=""
                className="dark:invert"
              />
            )}
          </span>
        </div>

        <div className="mx-auto mt-4 flex w-full max-w-md flex-col gap-4 rounded-3xl border border-neutral-200 p-4 dark:border-neutral-700">
          <div className="flex items-center justify-center gap-2">
            {discountPercent != null && (
              <span className="rounded-full bg-red-50 px-2 py-0.5 text-xs font-bold text-red-500 dark:bg-red-500/10">
                {t("shops.discountPercentLabel", { percent: discountPercent })}
              </span>
            )}
            <h1 className="text-xl font-bold">{listing.title}</h1>
          </div>

          {images.length > 0 && (
            <div className="relative">
              <div
                onScroll={handleImageScroll}
                className="flex w-full snap-x snap-mandatory gap-0 overflow-x-auto rounded-2xl [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
              >
                {images.map((img) => (
                  <div
                    key={img}
                    className="relative aspect-[4/3] w-full shrink-0 snap-center overflow-hidden bg-neutral-200 dark:bg-neutral-800"
                  >
                    <Image
                      src={IMAGE_BASE_URL + img}
                      alt={listing.title}
                      fill
                      className="object-cover"
                      sizes="400px"
                      unoptimized
                    />
                  </div>
                ))}
              </div>
              {images.length > 1 && (
                <span className="absolute bottom-2 left-1/2 -translate-x-1/2 rounded-full bg-black/50 px-2 py-0.5 text-[10px] font-bold text-white">
                  {activeImageIndex + 1}/{images.length}
                </span>
              )}
            </div>
          )}

          <p className="text-sm font-bold">{t("shops.specsTitle")}</p>

          {categoryLine && (
            <SpecRow label={t("shops.categorySpecLabel")}>
              <span className="text-xs">{categoryLine}</span>
            </SpecRow>
          )}

          {colors.length > 0 && (
            <SpecRow label={t("shops.colorLabel")}>
              {colors.map((color) => (
                <button
                  key={color}
                  type="button"
                  onClick={() => setSelectedColor(color)}
                  className={cn(
                    "rounded-full border px-2.5 py-1 text-xs",
                    selectedColor === color
                      ? "border-pink-500 bg-pink-500 text-white"
                      : "border-neutral-300 dark:border-neutral-600"
                  )}
                >
                  {color}
                </button>
              ))}
            </SpecRow>
          )}

          {sizes.length > 0 && (
            <SpecRow label={t("shops.sizeLabel")}>
              {sizes.map((size) => (
                <button
                  key={size}
                  type="button"
                  onClick={() => setSelectedSize(size)}
                  className={cn(
                    "rounded-full border px-2.5 py-1 text-xs",
                    selectedSize === size
                      ? "border-pink-500 bg-pink-500 text-white"
                      : "border-neutral-300 dark:border-neutral-600"
                  )}
                >
                  {size}
                </button>
              ))}
            </SpecRow>
          )}

          {weights.length > 0 && (
            <SpecRow label={t("shops.weightLabel")}>
              {weights.map((weight) => (
                <button
                  key={weight}
                  type="button"
                  onClick={() => setSelectedWeight(weight)}
                  className={cn(
                    "rounded-full border px-2.5 py-1 text-xs",
                    selectedWeight === weight
                      ? "border-pink-500 bg-pink-500 text-white"
                      : "border-neutral-300 dark:border-neutral-600"
                  )}
                >
                  {weight}
                </button>
              ))}
            </SpecRow>
          )}

          {listing.description && (
            <SpecRow label={t("shops.descriptionLabel")}>
              <span className="text-xs leading-relaxed">
                {descriptionExpanded || listing.description.length <= 50
                  ? listing.description
                  : `${listing.description.slice(0, 50)}...`}
                {listing.description.length > 50 && (
                  <button
                    type="button"
                    onClick={() => setDescriptionExpanded((v) => !v)}
                    className="mr-1 font-bold text-pink-500"
                  >
                    {descriptionExpanded ? t("shops.showLess") : t("shops.showMore")}
                  </button>
                )}
              </span>
            </SpecRow>
          )}

          <div className="flex items-center gap-2">
            <span className="flex-1 rounded-3xl bg-green-600 py-2.5 text-center text-sm font-bold text-white">
              {t("shops.manageStockButton")}
            </span>
            <button
              type="button"
              disabled={!matchedVariant || savingStock}
              onClick={() => adjustStock(-1)}
              className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-green-600 text-lg font-bold text-white disabled:opacity-50"
            >
              −
            </button>
            <span className="w-8 shrink-0 text-center text-sm font-bold">
              {matchedVariant?.stock ?? 0}
            </span>
            <button
              type="button"
              disabled={!matchedVariant || savingStock}
              onClick={() => adjustStock(1)}
              className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-green-600 text-lg font-bold text-white disabled:opacity-50"
            >
              +
            </button>
          </div>

          {matchedVariant && (
            <SpecRow label={t("shops.priceSpecLabel")}>
              {matchedVariant.discount_price ? (
                <span className="flex items-center gap-2">
                  <span className="text-xs text-neutral-400 line-through">
                    {matchedVariant.price.toLocaleString()} {t("settings.toman")}
                  </span>
                  <span className="text-sm font-bold text-red-500">
                    {matchedVariant.discount_price.toLocaleString()} {t("settings.toman")}
                  </span>
                </span>
              ) : (
                <span className="text-sm font-bold">
                  {matchedVariant.price.toLocaleString()} {t("settings.toman")}
                </span>
              )}
            </SpecRow>
          )}
        </div>

        <div className="mx-auto mb-6 mt-8 flex w-full max-w-md gap-3">
          <button
            type="button"
            onClick={handleEdit}
            className="flex-1 rounded-3xl bg-neutral-900 py-3 text-sm font-bold text-white dark:bg-neutral-800"
          >
            {t("shops.editProductButton")}
          </button>
          <button
            type="button"
            onClick={toggleActive}
            disabled={savingStatus}
            className={cn(
              "flex-1 rounded-3xl py-3 text-sm font-bold text-white disabled:opacity-50",
              isInactive ? "bg-green-600" : "bg-red-500"
            )}
          >
            {isInactive ? t("shops.activateButton") : t("shops.deactivateButton")}
          </button>
        </div>
      </Container>
      </LocalePageShell>
      <TabNavigation currentPage="/settings" />
    </>
  );
}
