"use client";

import Link from "next/link";
import Image from "next/image";
import { Minus, Plus, Trash2 } from "lucide-react";
import { Fragment, useEffect, useRef, useState } from "react";
import { formatPrice } from "@/lib/cart";
import { useCart, useCartTotals } from "./cart-provider";
import { EmptyState } from "./ui";

export function CartView() {
  const { updateQuantity, removeItem, undoRemove, pendingRemoval, getDish, ordersEnabled, orderComment, setOrderComment } = useCart();
  const totals = useCartTotals();
  const [removingIds, setRemovingIds] = useState<Set<string>>(() => new Set());
  const [undoSeconds, setUndoSeconds] = useState(0);
  const [undoProgress, setUndoProgress] = useState(0);
  const removalTimeouts = useRef<number[]>([]);

  useEffect(() => () => removalTimeouts.current.forEach((timeout) => window.clearTimeout(timeout)), []);

  useEffect(() => {
    if (!pendingRemoval) {
      setUndoSeconds(0);
      setUndoProgress(0);
      return;
    }

    let animationFrame = 0;
    const updateRemaining = () => {
      const remaining = Math.max(0, pendingRemoval.expiresAt - Date.now());
      setUndoSeconds(Math.ceil(remaining / 1000));
      setUndoProgress(Math.min(1, remaining / 3000));
      if (remaining > 0) animationFrame = window.requestAnimationFrame(updateRemaining);
    };
    updateRemaining();
    return () => window.cancelAnimationFrame(animationFrame);
  }, [pendingRemoval]);

  const scheduleRemove = (dishId: string) => {
    if (removingIds.has(dishId)) return;
    setRemovingIds((current) => new Set(current).add(dishId));
    const timeout = window.setTimeout(() => {
      removeItem(dishId);
      setRemovingIds((current) => {
        const next = new Set(current);
        next.delete(dishId);
        return next;
      });
    }, 240);
    removalTimeouts.current.push(timeout);
  };

  const pendingDish = pendingRemoval ? getDish(pendingRemoval.item.dishId) : null;
  const pendingLine = pendingDish ? (
    <div className="cart-line-shell" role="status" aria-live="polite">
      <article className="card grid min-h-0 gap-4 p-4 md:grid-cols-[120px_1fr_auto]">
        <div className="relative aspect-square overflow-hidden rounded-md bg-kiln-iron">
          <Image src={pendingDish.image} alt={pendingDish.imageAlt || pendingDish.name} fill sizes="120px" className="object-cover" />
        </div>
        <div>
          <h2 className="text-xl">{pendingDish.name}</h2>
          <p className="muted">{pendingDish.weight} · {formatPrice(pendingDish.price)}</p>
          <p className="mt-2 text-sm text-kiln-flame">Товар удалён · вернуть можно ещё {undoSeconds} с</p>
        </div>
        <div className="flex min-w-[116px] flex-col items-stretch justify-center gap-2">
          <button type="button" className="button undo-button" onClick={undoRemove}>
            <span className="undo-button-fill" style={{ width: `${undoProgress * 100}%` }} aria-hidden="true" />
            <span className="relative z-10">Вернуть</span>
          </button>
        </div>
      </article>
    </div>
  ) : null;

  if (!ordersEnabled) {
    return <EmptyState title="Заказы временно отключены" text="Онлайн-приём заказов будет включён позже." action={<Link href="/menu" className="button button-secondary">Вернуться в меню</Link>} />;
  }
  if (!totals.lines.length && !pendingLine) {
    return (
      <EmptyState
        title="Корзина пустая"
        text="Выберите блюда из меню или доставки. Корзина сохранится после перезагрузки страницы."
        action={<div className="flex flex-wrap justify-center gap-3"><Link href="/menu" className="button button-secondary">Вернуться в меню</Link><Link href="/delivery" className="button button-primary">Перейти в доставку</Link></div>}
      />
    );
  }

  return (
    <div className="grid gap-6 lg:grid-cols-[1fr_360px]">
      <div className="grid max-w-3xl gap-3">
        {totals.lines.map((line, index) =>
          <Fragment key={line?.dish.id || `empty-${index}`}>
          {pendingRemoval?.index === index ? pendingLine : null}
          {line ? (
            <div className={`cart-line-shell ${removingIds.has(line.dish.id) ? "is-removing" : ""}`} aria-hidden={removingIds.has(line.dish.id)}>
            <article className="card grid min-h-0 gap-4 p-4 md:grid-cols-[120px_1fr_auto]">
              <div className="relative aspect-square overflow-hidden rounded-md bg-kiln-iron">
                <Image src={line.dish.image} alt={line.dish.imageAlt || line.dish.name} fill sizes="120px" className="object-cover" />
              </div>
              <div>
                <h2 className="text-xl">{line.dish.name}</h2>
                <p className="muted">{line.dish.weight} · {formatPrice(line.dish.price)}</p>
                {line.unavailable ? <p className="mt-2 text-sm text-kiln-flame">Позиция недоступна для интернет-заказа.</p> : null}
              </div>
              <div className="flex items-center justify-between gap-3 md:flex-col md:items-end">
                <strong className="text-kiln-flame">{formatPrice(line.lineTotal)}</strong>
                <div className="flex items-center gap-2">
                  <button className="button button-secondary px-3" aria-label="Уменьшить" onClick={() => line.quantity === 1 ? scheduleRemove(line.dish.id) : updateQuantity(line.dish.id, line.quantity - 1)}>
                    <Minus size={16} />
                  </button>
                  <span className="w-8 text-center">{line.quantity}</span>
                  <button className="button button-secondary px-3" aria-label="Увеличить" onClick={() => updateQuantity(line.dish.id, line.quantity + 1)}>
                    <Plus size={16} />
                  </button>
                  <button className="button button-secondary px-3" aria-label="Удалить" onClick={() => scheduleRemove(line.dish.id)}>
                    <Trash2 size={16} />
                  </button>
                </div>
              </div>
            </article>
            </div>
          ) : null}
          </Fragment>
        )}
        {pendingRemoval && pendingRemoval.index >= totals.lines.length ? pendingLine : null}
        <label className="mt-2 block"><span className="mb-1 block text-sm">Комментарий</span><textarea className="input min-h-24" maxLength={160} value={orderComment} onChange={(event) => setOrderComment(event.target.value)} placeholder="Комментарий ко всему заказу" /><span className="mt-1 block text-right text-xs muted">{orderComment.length}/160</span></label>
      </div>
      <aside className="card h-fit p-5">
        <h2 className="text-2xl">Итого</h2>
        <div className="mt-4 grid gap-2 text-sm">
          <div className="flex justify-between"><span>Блюда</span><strong>{formatPrice(totals.subtotal)}</strong></div>
          <div className="flex justify-between"><span>Доставка</span><strong>{formatPrice(totals.delivery)}</strong></div>
          <div className="flex justify-between border-t border-white/10 pt-3 text-lg"><span>К оплате</span><strong>{formatPrice(totals.total)}</strong></div>
        </div>
        {totals.belowMinimum ? <p className="mt-4 text-sm text-kiln-flame">Минимальная сумма зависит от зоны доставки и будет проверена при оформлении.</p> : null}
        <Link href="/checkout" className="button button-primary mt-5 w-full">
          Оформить заказ
        </Link>
        <Link href="/menu" className="button button-secondary mt-3 w-full">
          Вернуться в меню
        </Link>
      </aside>
    </div>
  );
}
