"use client";

import * as React from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Search, Star, X } from "lucide-react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { EmptyState } from "@/components/shared/empty-state";
import { cn } from "@/lib/utils";
import { setFavorite } from "@/lib/actions/favorites";
import { servicesTexts as tx } from "@/lib/i18n/services";
import { platformMeta } from "./platform";
import { ServiceDetailsDialog } from "./service-details-dialog";
import type { CatalogDTO, PlatformKey, ServiceRowDTO } from "./types";

type PlatformFilter = PlatformKey | "ALL";

function Chip({
  active,
  onClick,
  children,
  className,
}: {
  active: boolean;
  onClick: () => void;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      aria-pressed={active}
      className={cn(
        "inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors",
        active
          ? "border-primary bg-primary text-primary-foreground"
          : "border-border bg-card text-muted-foreground hover:bg-muted hover:text-foreground",
        className,
      )}
    >
      {children}
    </button>
  );
}

export function ServicesCatalog({
  catalog,
  signedIn,
}: {
  catalog: CatalogDTO;
  signedIn: boolean;
}) {
  const router = useRouter();
  const [query, setQuery] = React.useState("");
  const [platform, setPlatform] = React.useState<PlatformFilter>("ALL");
  const [favoritesOnly, setFavoritesOnly] = React.useState(false);
  const [details, setDetails] = React.useState<ServiceRowDTO | null>(null);
  const [, startTransition] = React.useTransition();

  const [favorites, setFavorites] = React.useState<Set<number>>(() => {
    const initial = new Set<number>();
    for (const group of catalog.categories) {
      for (const service of group.services) {
        if (service.favorite) initial.add(service.id);
      }
    }
    return initial;
  });

  const needle = query.trim().toLowerCase();

  const groups = React.useMemo(() => {
    const out: { id: string; name: string; platform: PlatformKey; services: ServiceRowDTO[] }[] =
      [];
    for (const group of catalog.categories) {
      if (platform !== "ALL" && group.platform !== platform) continue;
      const services = group.services.filter((service) => {
        if (favoritesOnly && !favorites.has(service.id)) return false;
        if (needle && !service.search.includes(needle)) return false;
        return true;
      });
      if (services.length === 0) continue;
      out.push({ ...group, services });
    }
    return out;
  }, [catalog.categories, platform, favoritesOnly, favorites, needle]);

  const shownServices = groups.reduce((sum, g) => sum + g.services.length, 0);
  const filtering = needle.length > 0 || platform !== "ALL" || favoritesOnly;

  function clearFilters() {
    setQuery("");
    setPlatform("ALL");
    setFavoritesOnly(false);
  }

  function toggleFavorite(serviceId: number) {
    const next = !favorites.has(serviceId);
    setFavorites((prev) => {
      const copy = new Set(prev);
      if (next) copy.add(serviceId);
      else copy.delete(serviceId);
      return copy;
    });

    startTransition(async () => {
      const result = await setFavorite(serviceId, next);
      if (!result.ok) {
        setFavorites((prev) => {
          const copy = new Set(prev);
          if (next) copy.delete(serviceId);
          else copy.add(serviceId);
          return copy;
        });
        toast.error(result.error || tx.favoriteFailed);
        return;
      }
      toast.success(next ? tx.favoriteAdded : tx.favoriteRemoved);
    });
  }

  function openService(service: ServiceRowDTO) {
    if (signedIn) router.push(`/?service=${service.id}`);
    else setDetails(service);
  }

  return (
    <div className="space-y-5">
      {/* toolbar */}
      <div className="rounded-2xl border bg-card p-4 shadow-sm">
        <div className="relative">
          <Search className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            placeholder={tx.searchPlaceholder}
            aria-label={tx.searchPlaceholder}
            className="h-10 rounded-lg pr-9 pl-9"
          />
          {query ? (
            <button
              type="button"
              onClick={() => setQuery("")}
              aria-label={tx.clearFilters}
              className="absolute top-1/2 right-2.5 -translate-y-1/2 rounded-md p-1 text-muted-foreground transition-colors hover:text-foreground"
            >
              <X className="size-3.5" />
            </button>
          ) : null}
        </div>

        <div className="mt-3 flex flex-wrap items-center gap-1.5">
          <Chip active={platform === "ALL"} onClick={() => setPlatform("ALL")}>
            {tx.platformAll}
          </Chip>
          {catalog.platforms.map((key) => {
            const meta = platformMeta(key);
            const Icon = meta.icon;
            return (
              <Chip
                key={key}
                active={platform === key}
                onClick={() => setPlatform(platform === key ? "ALL" : key)}
              >
                <Icon className="size-3.5" />
                {meta.label}
              </Chip>
            );
          })}
          {signedIn ? (
            <Chip
              active={favoritesOnly}
              onClick={() => setFavoritesOnly((v) => !v)}
              className={cn(
                favoritesOnly &&
                  "border-amber-500 bg-amber-500 text-white hover:bg-amber-500",
              )}
            >
              <Star
                className={cn("size-3.5", favoritesOnly && "fill-current")}
              />
              {tx.favoritesOnly}
              {favorites.size > 0 ? (
                <span className="font-mono opacity-80">{favorites.size}</span>
              ) : null}
            </Chip>
          ) : null}
        </div>

        <div className="mt-3 flex flex-wrap items-center justify-between gap-2 border-t pt-3 text-xs text-muted-foreground">
          <span>{tx.resultsSummary(shownServices, groups.length)}</span>
          <div className="flex items-center gap-3">
            {catalog.discounted ? (
              <span className="text-primary">{tx.discountApplied}</span>
            ) : null}
            {filtering ? (
              <button
                type="button"
                onClick={clearFilters}
                className="font-medium text-primary transition-colors hover:text-primary/80"
              >
                {tx.clearFilters}
              </button>
            ) : null}
          </div>
        </div>
      </div>

      {/* catalogue */}
      {groups.length === 0 ? (
        catalog.totalServices === 0 ? (
          <EmptyState title={tx.emptyCatalogTitle} hint={tx.emptyCatalogHint} />
        ) : favoritesOnly && favorites.size === 0 ? (
          <EmptyState
            icon={Star}
            title={tx.emptyFavoritesTitle}
            hint={tx.emptyFavoritesHint}
            action={
              <Button variant="outline" onClick={clearFilters}>
                {tx.clearFilters}
              </Button>
            }
          />
        ) : (
          <EmptyState
            icon={Search}
            title={tx.emptyTitle}
            hint={tx.emptyHint}
            action={
              <Button variant="outline" onClick={clearFilters}>
                {tx.clearFilters}
              </Button>
            }
          />
        )
      ) : (
        <div className="space-y-5">
          {groups.map((group) => {
            const meta = platformMeta(group.platform);
            const Icon = meta.icon;
            return (
              <section
                key={group.id}
                className="overflow-hidden rounded-2xl border bg-card shadow-sm"
              >
                <header className="flex flex-wrap items-center gap-3 border-b px-4 py-3 sm:px-5">
                  <div
                    className={cn(
                      "flex size-8 shrink-0 items-center justify-center rounded-lg",
                      meta.tint,
                    )}
                  >
                    <Icon className="size-4" />
                  </div>
                  <div className="min-w-0">
                    <h2 className="font-display truncate text-sm font-semibold sm:text-base">
                      {group.name}
                    </h2>
                    <p className="text-xs text-muted-foreground">
                      {meta.label} · {tx.serviceCount(group.services.length)}
                    </p>
                  </div>
                </header>

                <Table className="[&_td]:px-3 [&_td]:py-3 [&_td:first-child]:pl-5 [&_td:last-child]:pr-5 [&_th]:px-3 [&_th]:text-xs [&_th]:font-medium [&_th]:text-muted-foreground [&_th:first-child]:pl-5 [&_th:last-child]:pr-5">
                  <TableHeader>
                    <TableRow className="hover:bg-transparent">
                      {signedIn ? (
                        <TableHead className="w-10">
                          <span className="sr-only">{tx.colFavorite}</span>
                        </TableHead>
                      ) : null}
                      <TableHead className="w-20">{tx.colId}</TableHead>
                      <TableHead className="min-w-[240px]">{tx.colService}</TableHead>
                      <TableHead className="text-right whitespace-nowrap">
                        {tx.colRate}
                      </TableHead>
                      <TableHead className="text-right">{tx.colMin}</TableHead>
                      <TableHead className="text-right">{tx.colMax}</TableHead>
                      {catalog.showAverageTime ? (
                        <TableHead className="whitespace-nowrap">
                          {tx.colAverageTime}
                        </TableHead>
                      ) : null}
                      <TableHead className="w-24 text-right">
                        {tx.colDescription}
                      </TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {group.services.map((service) => {
                      const starred = favorites.has(service.id);
                      return (
                        <TableRow
                          key={service.id}
                          onClick={() => openService(service)}
                          className="cursor-pointer"
                        >
                          {signedIn ? (
                            <TableCell>
                              <button
                                type="button"
                                onClick={(event) => {
                                  event.stopPropagation();
                                  toggleFavorite(service.id);
                                }}
                                aria-label={
                                  starred ? tx.removeFromFavorites : tx.addToFavorites
                                }
                                aria-pressed={starred}
                                title={
                                  starred ? tx.removeFromFavorites : tx.addToFavorites
                                }
                                className={cn(
                                  "rounded-md p-1 transition-colors",
                                  starred
                                    ? "text-amber-500 hover:text-amber-600"
                                    : "text-muted-foreground/40 hover:text-amber-500",
                                )}
                              >
                                <Star
                                  className={cn("size-4", starred && "fill-current")}
                                />
                              </button>
                            </TableCell>
                          ) : null}

                          <TableCell className="font-mono text-xs text-muted-foreground">
                            {service.id}
                          </TableCell>

                          <TableCell>
                            <div className="font-medium">{service.name}</div>
                            <div className="mt-0.5 flex flex-wrap items-center gap-1.5 text-xs text-muted-foreground">
                              <span>{service.typeLabel}</span>
                              {service.refill ? (
                                <span className="text-emerald-600 dark:text-emerald-400">
                                  · {tx.featureRefill}
                                </span>
                              ) : null}
                              {service.cancel ? (
                                <span className="text-blue-600 dark:text-blue-400">
                                  · {tx.featureCancel}
                                </span>
                              ) : null}
                              {service.dripfeed ? (
                                <span className="text-cyan-600 dark:text-cyan-400">
                                  · {tx.featureDripFeed}
                                </span>
                              ) : null}
                            </div>
                          </TableCell>

                          <TableCell className="text-right whitespace-nowrap">
                            <span className="font-mono text-sm font-semibold">
                              {service.rateDisplay}
                            </span>
                            {service.hasCustomRate ? (
                              <span
                                title={tx.yourRateHint}
                                className="ml-1.5 rounded-full bg-cyan-100 px-1.5 py-0.5 text-[10px] font-medium text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-400"
                              >
                                {tx.yourRate}
                              </span>
                            ) : null}
                          </TableCell>

                          <TableCell className="text-right font-mono text-xs text-muted-foreground">
                            {service.minDisplay}
                          </TableCell>
                          <TableCell className="text-right font-mono text-xs text-muted-foreground">
                            {service.maxDisplay}
                          </TableCell>

                          {catalog.showAverageTime ? (
                            <TableCell className="text-xs whitespace-nowrap text-muted-foreground">
                              {service.averageTime}
                            </TableCell>
                          ) : null}

                          <TableCell className="text-right">
                            <Button
                              variant="outline"
                              size="xs"
                              onClick={(event) => {
                                event.stopPropagation();
                                setDetails(service);
                              }}
                            >
                              {tx.viewDescription}
                            </Button>
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>

              </section>
            );
          })}
        </div>
      )}

      {!signedIn ? (
        <div className="rounded-2xl border border-primary/20 bg-gradient-to-br from-primary/10 via-card to-cyan-500/10 p-6 shadow-sm sm:p-8">
          <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
            <div className="max-w-xl space-y-1.5">
              <h2 className="font-display text-lg font-semibold tracking-tight sm:text-xl">
                {tx.ctaTitle}
              </h2>
              <p className="text-sm text-muted-foreground">{tx.ctaBody}</p>
            </div>
            <div className="flex shrink-0 flex-wrap items-center gap-2">
              <Button asChild size="lg">
                <Link href="/signup">{tx.ctaSignUp}</Link>
              </Button>
              <Button asChild variant="outline" size="lg">
                <Link href="/signin">{tx.ctaSignIn}</Link>
              </Button>
            </div>
          </div>
        </div>
      ) : null}

      <ServiceDetailsDialog
        service={details}
        signedIn={signedIn}
        showAverageTime={catalog.showAverageTime}
        onOpenChange={(open) => {
          if (!open) setDetails(null);
        }}
      />
    </div>
  );
}

export default ServicesCatalog;
