"use client";

import { Chip, Separator } from "@heroui/react";
import Image from "next/image";
import Link from "next/link";
import { formatPrice } from "@repo/utils";
import { getCartItemProductUrl } from "@/lib/cart/constants";
import type {
  CheckoutValidatedItem,
  CheckoutItemIssue,
} from "@/lib/checkout/types";

const PLACEHOLDER_IMAGE = "/images/placeholder-product.png";

type CheckoutLineItemsProps = {
  items: CheckoutValidatedItem[];
  issues: CheckoutItemIssue[];
};

function getItemIssues(
  variantId: string,
  productId: string,
  issues: CheckoutItemIssue[],
): CheckoutItemIssue[] {
  return issues.filter((issue) => {
    if ("variantId" in issue) return issue.variantId === variantId;
    if ("productId" in issue) return issue.productId === productId;
    return false;
  });
}

function isItemUnavailable(itemIssues: CheckoutItemIssue[]): boolean {
  return itemIssues.some(
    (i) =>
      i.type === "out_of_stock" ||
      i.type === "variant_inactive" ||
      i.type === "variant_not_found" ||
      i.type === "product_not_found",
  );
}

export function CheckoutLineItems({ items, issues }: CheckoutLineItemsProps) {
  if (items.length === 0) return null;

  return (
    <>
      {/* Mobile: stacked card layout */}
      <div className="flex flex-col gap-0 md:hidden" role="list" aria-label="Order items">
        {items.map((item, i) => (
          <div key={item.variantId} role="listitem">
            <MobileItemCard
              item={item}
              itemIssues={getItemIssues(item.variantId, item.productId, issues)}
            />
            {i < items.length - 1 && <Separator className="my-3" />}
          </div>
        ))}
      </div>

      {/* Tablet+: table layout */}
      <table className="hidden w-full md:table">
        <caption className="sr-only">Order items</caption>
        <thead>
          <tr className="border-b border-default-200 text-left text-sm text-default-500">
            <th scope="col" className="pb-3 font-medium">
              Product
            </th>
            <th scope="col" className="pb-3 font-medium">
              Price
            </th>
            <th scope="col" className="pb-3 text-center font-medium">
              Qty
            </th>
            <th scope="col" className="pb-3 text-right font-medium">
              Total
            </th>
            <th scope="col" className="pb-3 text-right font-medium">
              Status
            </th>
          </tr>
        </thead>
        <tbody>
          {items.map((item) => (
            <TableRow
              key={item.variantId}
              item={item}
              itemIssues={getItemIssues(
                item.variantId,
                item.productId,
                issues,
              )}
            />
          ))}
        </tbody>
      </table>
    </>
  );
}

function MobileItemCard({
  item,
  itemIssues,
}: {
  item: CheckoutValidatedItem;
  itemIssues: CheckoutItemIssue[];
}) {
  const unavailable = isItemUnavailable(itemIssues);
  const productUrl = getCartItemProductUrl(item);
  const lineTotal = item.unitPrice * item.quantity;

  return (
    <div className={`flex items-start gap-3 py-1 ${unavailable ? "opacity-50" : ""}`}>
      <Link
        href={productUrl}
        className="relative block size-16 shrink-0 overflow-hidden rounded-xl bg-default-100"
      >
        <Image
          src={item.imageUrl ?? PLACEHOLDER_IMAGE}
          alt=""
          width={64}
          height={64}
          className="object-cover"
          unoptimized={!(item.imageUrl ?? "").startsWith("http")}
        />
      </Link>

      <div className="flex min-w-0 flex-1 flex-col gap-1.5">
        <div className="min-w-0">
          <Link
            href={productUrl}
            className="line-clamp-2 text-sm font-medium text-foreground hover:underline"
          >
            {item.productName}
          </Link>
          {item.variantName && (
            <Chip
              size="sm"
              variant="soft"
              className="mt-1 bg-[#e8f7f6] text-foreground"
            >
              {item.variantName}
            </Chip>
          )}
        </div>

        <IssueBadges issues={itemIssues} />

        <div className="flex flex-wrap items-center justify-between gap-2">
          <span className="text-sm text-default-500">
            {formatPrice(item.unitPrice)} &times; {item.quantity}
          </span>
          <span className="text-sm font-semibold text-[#236f6b]">
            {formatPrice(lineTotal)}
          </span>
        </div>
      </div>
    </div>
  );
}

function TableRow({
  item,
  itemIssues,
}: {
  item: CheckoutValidatedItem;
  itemIssues: CheckoutItemIssue[];
}) {
  const unavailable = isItemUnavailable(itemIssues);
  const productUrl = getCartItemProductUrl(item);
  const lineTotal = item.unitPrice * item.quantity;

  return (
    <tr
      className={`border-b border-default-100 ${unavailable ? "opacity-50" : ""}`}
    >
      {/* Product */}
      <td className="py-4 pr-4">
        <div className="flex items-center gap-3">
          <Link
            href={productUrl}
            className="relative block size-14 shrink-0 overflow-hidden rounded-xl bg-default-100"
          >
            <Image
              src={item.imageUrl ?? PLACEHOLDER_IMAGE}
              alt=""
              width={56}
              height={56}
              className="object-cover"
              unoptimized={!(item.imageUrl ?? "").startsWith("http")}
            />
          </Link>
          <div className="min-w-0">
            <Link
              href={productUrl}
              className="line-clamp-2 text-sm font-medium text-foreground hover:underline"
            >
              {item.productName}
            </Link>
            {item.variantName && (
              <Chip
                size="sm"
                variant="soft"
                className="mt-1 bg-[#e8f7f6] text-foreground"
              >
                {item.variantName}
              </Chip>
            )}
          </div>
        </div>
      </td>

      {/* Price */}
      <td className="py-4 text-sm text-foreground">
        {formatPrice(item.unitPrice)}
      </td>

      {/* Qty */}
      <td className="py-4 text-center text-sm text-foreground">
        {item.quantity}
      </td>

      {/* Line total */}
      <td className="py-4 text-right text-sm font-semibold text-[#236f6b]">
        {formatPrice(lineTotal)}
      </td>

      {/* Status */}
      <td className="py-4 text-right">
        <IssueBadges issues={itemIssues} />
      </td>
    </tr>
  );
}

function IssueBadges({ issues }: { issues: CheckoutItemIssue[] }) {
  if (issues.length === 0) return null;

  return (
    <div className="flex flex-wrap gap-1.5">
      {issues.map((issue, i) => (
        <IssueBadge key={`${issue.type}-${i}`} issue={issue} />
      ))}
    </div>
  );
}

function IssueBadge({ issue }: { issue: CheckoutItemIssue }) {
  switch (issue.type) {
    case "out_of_stock":
      return (
        <Chip size="sm" variant="soft" className="bg-danger-50 text-danger">
          Out of stock
        </Chip>
      );
    case "insufficient_stock":
      return (
        <Chip size="sm" variant="soft" className="bg-warning-50 text-warning-600">
          Only {issue.available} left
        </Chip>
      );
    case "price_changed":
      return (
        <Chip size="sm" variant="soft" className="bg-primary-50 text-primary">
          Price updated: {formatPrice(issue.oldPrice)} &rarr;{" "}
          {formatPrice(issue.newPrice)}
        </Chip>
      );
    case "variant_inactive":
    case "variant_not_found":
    case "product_not_found":
      return (
        <Chip size="sm" variant="soft" className="bg-danger-50 text-danger">
          Unavailable
        </Chip>
      );
  }
}
