'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { ShieldCheck, GitFork, Activity } from 'lucide-react';
import { apiFetch } from '@/lib/api';
import { cn } from '@/lib/cn';
import { Logo } from '@/components/logo';
import { Input } from '@/components/input';
import { MobileActionBar } from '@/components/mobile-action-bar';
import { UserMenu } from '@/components/user-menu';

interface Template {
  id: string;
  slug: string;
  title: string;
  shortDescription: string;
  category: string;
  status: 'draft' | 'public' | 'hidden' | 'takedown';
  verified: boolean;
  forkCount: number;
  activeDeployments: number;
  ownerName: string | null;
  ownerOrgName: string | null;
  sourceServerId: string | null;
  createdAt: string;
}

type Sort = 'trending' | 'top';
type Scope = 'all' | 'mine';

const STATUS_STYLE: Record<Template['status'], string> = {
  public: 'border-emerald-400/40 bg-emerald-400/10 text-emerald-300',
  hidden: 'border-amber-400/40 bg-amber-400/10 text-amber-300',
  takedown: 'border-red-400/40 bg-red-400/10 text-red-300',
  draft: 'border-zinc-400/40 bg-zinc-400/10 text-zinc-300',
};

export default function TemplatesMarketplace() {
  const [me, setMe] = useState<{ email: string } | null | undefined>(undefined);
  const [scope, setScope] = useState<Scope>('all');
  const [templates, setTemplates] = useState<Template[] | null>(null);
  const [categories, setCategories] = useState<string[]>([]);
  const [sort, setSort] = useState<Sort>('trending');
  const [category, setCategory] = useState('');
  const [search, setSearch] = useState('');

  // Detect login state once
  useEffect(() => {
    apiFetch<{ user: { email: string } }>('/v1/auth/me')
      .then((r) => setMe({ email: r.user.email }))
      .catch(() => setMe(null));
  }, []);

  // Load templates whenever scope/sort/category changes
  useEffect(() => {
    setTemplates(null);
    if (scope === 'mine') {
      apiFetch<{ templates: Template[]; categories: string[] }>('/v1/templates/mine')
        .then((r) => {
          setTemplates(r.templates);
          setCategories(r.categories);
        })
        .catch(() => setTemplates([]));
    } else {
      const params = new URLSearchParams({ sort });
      if (category) params.set('category', category);
      apiFetch<{ templates: Template[]; categories: string[] }>(`/v1/templates?${params}`)
        .then((r) => {
          setTemplates(r.templates);
          setCategories(r.categories);
        })
        .catch(() => setTemplates([]));
    }
  }, [scope, sort, category]);

  const visible = templates?.filter((t) => {
    if (search) {
      const q = search.toLowerCase();
      if (!t.title.toLowerCase().includes(q) && !t.shortDescription.toLowerCase().includes(q)) {
        return false;
      }
    }
    // category filter is server-side for 'all', client-side for 'mine'
    if (scope === 'mine' && category && t.category !== category) return false;
    return true;
  });

  const loggedIn = me != null;

  return (
    <div className="flex min-h-screen flex-col">
      <header className="sticky top-0 z-50 border-b border-[--color-border] bg-[--color-bg]/85 backdrop-blur-md">
        <div className="mx-auto flex h-12 max-w-6xl items-center justify-between gap-2 px-4 sm:px-6">
          <div className="flex min-w-0 items-center gap-3">
            <Logo />
            {/* "/ templates" subtitle is redundant on mobile — h1 below
                already names the page. Keep on desktop as breadcrumb. */}
            <span className="hidden text-[12.5px] text-[--color-fg-subtle] sm:inline">
              / templates
            </span>
          </div>
          <nav className="flex items-center gap-1.5 sm:gap-2">
            {loggedIn ? (
              <>
                {/* Dashboard link + "+ New server" pill hidden on mobile —
                    the UserMenu (avatar) + the MobileActionBar below cover
                    both navigation paths there. */}
                <Link
                  href="/dashboard"
                  className="hidden text-[12.5px] text-[--color-fg-muted] transition-colors hover:text-[--color-fg] sm:inline"
                >
                  Dashboard
                </Link>
                <Link
                  href="/servers/new"
                  className="hidden h-7 items-center gap-1.5 rounded-md bg-[--color-accent] px-2.5 text-[12px] font-medium text-white transition-colors duration-200 hover:bg-[#5557e8] sm:inline-flex"
                >
                  + New server
                </Link>
                <UserMenu />
              </>
            ) : (
              <>
                <Link
                  href="/"
                  className="hidden text-[12.5px] text-[--color-fg-muted] transition-colors hover:text-[--color-fg] sm:inline"
                >
                  Home
                </Link>
                <Link
                  href="/login"
                  className="rounded-md bg-[--color-accent] px-2.5 py-1 text-[12px] font-medium text-white transition-colors duration-200 hover:bg-[#5557e8] sm:px-3 sm:py-1.5 sm:text-[12.5px]"
                >
                  Start building
                </Link>
              </>
            )}
          </nav>
        </div>
      </header>

      <main
        className={cn(
          'mx-auto w-full max-w-6xl flex-1 px-4 py-8 sm:px-6 sm:py-12',
          // Bottom-bar clearance on mobile for logged-in users only — the
          // MobileActionBar is fixed bottom and would overlap the last row
          // of template cards otherwise.
          loggedIn && 'pb-24 sm:pb-12',
        )}
      >
        <header className="mb-6 max-w-2xl sm:mb-8">
          <div className="text-[11px] uppercase tracking-[0.16em] text-[--color-fg-subtle]">
            Marketplace
          </div>
          <h1 className="mt-2 text-[24px] font-semibold tracking-tight sm:text-[32px]">
            MCP server templates
          </h1>
          <p className="mt-2 text-[13px] leading-relaxed text-[--color-fg-muted] sm:mt-3 sm:text-[14px]">
            Pre-built MCP servers from the community. Fork in one click — your own container, your
            own credentials, fully isolated. The template author never sees your data.
          </p>
        </header>

        {/* Filter row: stacks vertically on mobile (search on top for thumb
            reach), inline on desktop. The order utility on the Input flips
            it to the right side at sm: while filters wrap normally. */}
        <div className="mb-6 flex flex-col gap-3 border-b border-[--color-border] pb-4 sm:flex-row sm:flex-wrap sm:items-center">
          <Input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search…"
            className="order-first w-full sm:order-last sm:ml-auto sm:w-60"
          />

          {/* Chips row — horizontally scrollable on narrow mobile so the
              segmented controls never get squeezed below their min-width. */}
          <div className="-mx-1 flex items-center gap-2 overflow-x-auto px-1 sm:m-0 sm:flex-wrap sm:gap-3 sm:overflow-visible sm:p-0">
            {loggedIn && (
              <>
                <div className="flex shrink-0 gap-1 rounded-md border border-[--color-border] bg-[--color-bg-subtle] p-0.5">
                  {(['all', 'mine'] as Scope[]).map((s) => (
                    <button
                      key={s}
                      type="button"
                      onClick={() => setScope(s)}
                      className={cn(
                        'rounded-[4px] px-2.5 py-1 text-[12.5px] capitalize transition-colors',
                        s === scope
                          ? 'bg-[--color-bg-elevated] text-[--color-fg]'
                          : 'text-[--color-fg-muted] hover:text-[--color-fg]',
                      )}
                    >
                      {s === 'all' ? 'All' : 'Mine'}
                    </button>
                  ))}
                </div>
                <div className="hidden h-4 w-px shrink-0 bg-[--color-border] sm:block" />
              </>
            )}

            {scope === 'all' && (
              <>
                <div className="flex shrink-0 gap-1">
                  {(['trending', 'top'] as Sort[]).map((s) => (
                    <button
                      key={s}
                      type="button"
                      onClick={() => setSort(s)}
                      className={cn(
                        'rounded-md px-2.5 py-1 text-[12.5px] capitalize transition-colors',
                        s === sort
                          ? 'bg-[--color-bg-elevated] text-[--color-fg]'
                          : 'text-[--color-fg-muted] hover:text-[--color-fg]',
                      )}
                    >
                      {s}
                    </button>
                  ))}
                </div>
                <div className="hidden h-4 w-px shrink-0 bg-[--color-border] sm:block" />
              </>
            )}

            <select
              value={category}
              onChange={(e) => setCategory(e.target.value)}
              // Hard width-cap — without it a long category name in the
              // selected slot would blow the chip row out on mobile and
              // push the scrollable region beyond the viewport. Native
              // <select> truncates the visible label with ellipsis when
              // the box is narrower than the text; the dropdown panel
              // itself still shows full names when opened.
              className="h-7 w-[140px] shrink-0 truncate rounded-md border border-[--color-border] bg-[--color-bg-subtle] px-2 text-[12.5px] focus:border-[--color-accent] focus:outline-none sm:w-[160px]"
            >
              <option value="">All categories</option>
              {categories.map((c) => (
                <option key={c} value={c}>
                  {c}
                </option>
              ))}
            </select>
          </div>
        </div>

        {!visible && <p className="mono text-[12px] text-[--color-fg-muted]">Loading…</p>}

        {visible && visible.length === 0 && (
          <div className="panel p-12 text-center">
            {scope === 'mine' ? (
              <>
                <p className="text-[14px] text-[--color-fg]">You haven&apos;t published any templates.</p>
                <p className="mt-1 text-[12.5px] text-[--color-fg-muted]">
                  Build a server, then tick <span className="mono">Share as template</span> on the
                  done screen — or use the Publish tab on any live server.
                </p>
              </>
            ) : (
              <>
                <p className="text-[14px] text-[--color-fg]">No templates yet.</p>
                <p className="mt-1 text-[12.5px] text-[--color-fg-muted]">
                  Build a server you&apos;re proud of and share it to the marketplace.
                </p>
              </>
            )}
          </div>
        )}

        {visible && visible.length > 0 && (
          <div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
            {visible.map((t) => (
              <TemplateCard key={t.id} t={t} showStatus={scope === 'mine'} />
            ))}
          </div>
        )}
      </main>

      <footer className="border-t border-[--color-border] py-8">
        <div className="mx-auto max-w-6xl px-4 text-[12px] text-[--color-fg-subtle] sm:px-6">
          Every template is isolated: forking creates your own container with your own secrets.
        </div>
      </footer>

      {/* Mobile tab-bar — only when signed in. Logged-out marketplace
          browsing keeps the simple marketing chrome (login CTA in header). */}
      {loggedIn && <MobileActionBar />}
    </div>
  );
}

function TemplateCard({ t, showStatus }: { t: Template; showStatus: boolean }) {
  // takedown templates can't be opened (the detail route 410s); link to the
  // server's Publish tab so the owner can see why. Everything else opens detail.
  const href =
    t.status === 'takedown' && t.sourceServerId
      ? `/servers/${t.sourceServerId}`
      : `/templates/${t.slug}`;

  return (
    <Link
      href={href}
      className="panel flex flex-col p-4 transition-colors duration-200 hover:border-[--color-border-strong]"
    >
      <div className="flex items-start justify-between gap-2">
        <div className="flex items-center gap-1.5">
          <h2 className="text-[14.5px] font-semibold tracking-tight">{t.title}</h2>
          {t.verified && (
            <span
              className="inline-flex items-center gap-0.5 rounded-full border border-[--color-accent]/40 bg-[--color-accent]/10 px-1.5 py-0.5 text-[9.5px] font-medium text-[--color-accent]"
              title="Verified by BuildMyMCPServer"
            >
              <ShieldCheck size={9} /> verified
            </span>
          )}
        </div>
        {showStatus ? (
          <span
            className={cn(
              'mono rounded-full border px-1.5 py-0.5 text-[9.5px]',
              STATUS_STYLE[t.status],
            )}
          >
            {t.status}
          </span>
        ) : (
          <span className="mono rounded-full border border-[--color-border] bg-[--color-bg-subtle] px-1.5 py-0.5 text-[10px] text-[--color-fg-subtle]">
            {t.category}
          </span>
        )}
      </div>
      <p className="mt-2 flex-1 text-[12.5px] leading-relaxed text-[--color-fg-muted]">
        {t.shortDescription}
      </p>
      <div className="mt-4 flex items-center justify-between text-[11px] text-[--color-fg-subtle]">
        <div className="flex items-center gap-3">
          <span className="inline-flex items-center gap-1 mono" title="Total forks">
            <GitFork size={11} />
            {t.forkCount}
          </span>
          <span className="inline-flex items-center gap-1 mono" title="Active deployments">
            <Activity size={11} />
            {t.activeDeployments}
          </span>
        </div>
        <span className="truncate">
          {showStatus ? t.category : `by ${t.ownerName ?? t.ownerOrgName ?? 'anonymous'}`}
        </span>
      </div>
    </Link>
  );
}
