"use client";

import type { Cart } from "@/services/models/Cart";
import type { PopulatedProduct } from "@/services/models/Product";

import clsx from "clsx";
import Image from "next/image";
import { useSearchParams } from "next/navigation";
import { useState, useTransition } from "react";

import LoadingSpinnerSVG from "@/assets/bars-scale.animated.svg";
import ChevronLeftSVG from "@/assets/icons/chevron-left.svg";
import ChevronRightSVG from "@/assets/icons/chevron-right.svg";

import Button from "@/components/Button/Button";

import { callAction } from "@/lib/action-utils";
import { addToCart, removeFromCart } from "@/services/actions/cartAPI";

import { isRedirectError } from "next/dist/client/components/redirect-error";
import toast from "react-hot-toast";
import styles from "./ProductCard.module.scss";

export default function ProductCard({
  product: { name, variants },
  cart,
}: {
  product: PopulatedProduct;
  cart: Cart | null;
}) {
  const [isPending, startTransition] = useTransition();

  const searchParams = useSearchParams();

  const colors = variants.map((variant) => variant.colorId);
  const colorQuery = searchParams.get("color");

  const [prevColorQuery, setPrevColorQuery] = useState(colorQuery);
  const [currentColor, setCurrentColor] = useState(
    colorQuery ?? colors.at(0)?.name,
  );

  const currentVariant = variants.find(
    (variant) => variant.colorId.name === currentColor,
  );

  if (!currentVariant) return;

  const { cover, coverBlur, price, discount } = currentVariant;
  const currentItem = cart?.items.find(
    (item) => item.sku === currentVariant.sku,
  );

  const discountValue = discount
    ? discount.type === "percent"
      ? (price / 100) * discount.value
      : discount.value
    : 0;
  const initialPrice = discount && price;
  const finalPrice = price - discountValue;
  const isDiscounted = initialPrice && initialPrice !== finalPrice;

  function handleAddToCart() {
    if (isPending) return;

    if (!currentVariant) throw new Error("Продукт больше не доступен");

    startTransition(() => {
      void toast.promise(
        callAction(
          addToCart(currentVariant._id.toString(), currentVariant.sku),
        ),
        {
          loading: "Добавляем в корзину...",
          success: "Продукт успешно добавлен",
          error: (error: unknown) => {
            if (isRedirectError(error)) return null;

            return error?.toString() ?? "Упс! Что-то пошло не так :(";
          },
        },
      );
    });
  }

  function handleRemoveFromCart() {
    if (isPending) return;

    if (!currentVariant || !currentItem)
      throw new Error("Продукт больше не доступен");

    startTransition(() => {
      void toast.promise(
        callAction(
          removeFromCart(currentVariant._id.toString(), currentVariant.sku),
        ),
        {
          loading: "Удаляем из корзины...",
          success: "Продукт успешно удален",
          error: (error: unknown) => {
            if (isRedirectError(error)) return null;

            return error?.toString() ?? "Упс! Что-то пошло не так :(";
          },
        },
      );
    });
  }

  function formatToCurrency(num: number) {
    return new Intl.NumberFormat("ru-RU", {
      style: "currency",
      currency: "RUB",
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    }).format(num);
  }

  if (colorQuery !== prevColorQuery) {
    setPrevColorQuery(colorQuery);
    setCurrentColor(colorQuery ?? colors.at(0)?.name);
  }

  return (
    <li className={styles["product-card"]}>
      <div className={styles["product-card__thumbnail-wrapper"]}>
        <Image
          key={cover}
          src={cover}
          alt={name}
          fill
          placeholder="blur"
          blurDataURL={coverBlur}
          className={styles["product-card__thumbnail"]}
        />

        <ul className={styles["product-card__color-switch-list"]}>
          {colors.map((color) => (
            <li
              key={color.name}
              className={styles["product-card__color-switch-list-item"]}
            >
              <Button
                onClick={() => {
                  setCurrentColor(color.name);
                }}
                className={clsx(
                  styles["product-card__color-switch"],
                  currentColor === color.name &&
                    styles["product-card__color-switch--selected"],
                )}
              >
                <Image
                  src={color.image.url}
                  alt={color.name}
                  fill
                  placeholder="blur"
                  blurDataURL={color.image.base64}
                  className={styles["product-card__color-switch-image"]}
                />
              </Button>
            </li>
          ))}
        </ul>

        <div className={styles["product-card__add-button-wrapper"]}>
          {currentItem ? (
            <div className={styles["product-card__button-wrapper"]}>
              <Button
                disabled={isPending}
                icon={ChevronLeftSVG}
                onClick={handleRemoveFromCart}
                className={styles["product-card__add-button"]}
              />

              <span className={styles["product-card__quantity"]}>
                {isPending ? (
                  <LoadingSpinnerSVG
                    className={styles["product-card__loader"]}
                  />
                ) : (
                  currentItem.quantity
                )}
              </span>

              <Button
                disabled={isPending}
                icon={ChevronRightSVG}
                onClick={handleAddToCart}
                className={styles["product-card__add-button"]}
              />
            </div>
          ) : (
            <Button
              variant="primary"
              size="large"
              icon={isPending ? LoadingSpinnerSVG : undefined}
              fill
              disabled={isPending}
              onClick={handleAddToCart}
              className={styles["product-card__add-button"]}
            >
              {!isPending && "Добавить в корзину"}
            </Button>
          )}
        </div>
      </div>

      <div className={styles["product-card__body"]}>
        <span className={styles["product-card__name"]}>{name}</span>

        <div className={styles["product-card__price-container"]}>
          <span
            className={clsx(
              styles["product-card__final-price"],
              isDiscounted && styles["product-card__final-price--accent"],
            )}
          >
            {formatToCurrency(finalPrice)}
          </span>

          {isDiscounted && (
            <span className={styles["product-card__initial-price"]}>
              {formatToCurrency(initialPrice)}
            </span>
          )}
        </div>
      </div>
    </li>
  );
}
