'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { Filter, Orbit, RefreshCw, Rocket, ShieldAlert, Sparkles, TrendingUp } from 'lucide-react';
import { Badge, Button, Input } from '@/components/ui/Primitives';
import { HermesShell, MetricCard, SectionCard } from '@/components/hermes-shell';
import { HermesInstanceBadge } from '@/components/hermes-instance-switcher';
import { useHermesInstance } from '@/lib/hermes-instance-context';
import { api, type Service, type ServiceHealth } from '@/lib/api';
import { getHermesProducts, getHermesTasks, hermesProducts, type HermesProduct } from '@/lib/hermes';

const views = [
  { key: 'all', label: 'All products' },
  { key: 'high-priority', label: 'High priority' },
  { key: 'needs-attention', label: 'Needs attention' },
  { key: 'no-recent-activity', label: 'No recent activity' },
  { key: 'repeated-failures', label: 'Repeated failures' },
  { key: 'recently-shipped', label: 'Recently shipped' },
] as const;

// --- Live services panel ----------------------------------------------------
//
// Replaces the previous fabricated 50-item mock with the real
// `backend/src/modules/services` registry as the primary view, joined with
// the health module. The 50-product seed data is still rendered below in a
// clearly-labelled "Planned products (seed)" section per Phase 3 ("optional
// manual entries for not-yet-deployed products come later").

function LiveServiceCard({ service, health }: { service: Service; health?: ServiceHealth }) {
  const status = health?.status ?? service.status;
  const statusVariant = status === 'up' ? 'success' : status === 'degraded' ? 'warning' : 'error';
  return (
    <div className="rounded-3xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-5 shadow-[var(--bl-shadow-sm)]">
      <div className="flex items-start justify-between gap-3">
        <div>
          <p className="font-semibold text-[var(--bl-text-primary)]">{service.name}</p>
          <p className="mt-1 text-xs text-[var(--bl-text-secondary)]">v{service.version}</p>
        </div>
        <Badge variant={statusVariant}>{status}</Badge>
      </div>
      <div className="mt-3 space-y-2 text-sm text-[var(--bl-text-secondary)]">
        <div className="break-all"><span className="text-[var(--bl-text-tertiary)]">Health URL:</span> <a className="hover:underline" href={service.healthUrl} target="_blank" rel="noreferrer">{service.healthUrl}</a></div>
        <div><span className="text-[var(--bl-text-tertiary)]">Repo:</span> {service.repoPath}</div>
        <div><span className="text-[var(--bl-text-tertiary)]">Last deploy:</span> {service.lastDeployedAt ? new Date(service.lastDeployedAt).toLocaleString() : '—'}</div>
        <div><span className="text-[var(--bl-text-tertiary)]">Last health check:</span> {health?.lastCheck ? new Date(health.lastCheck).toLocaleString() : (service.lastHealthCheckAt ? new Date(service.lastHealthCheckAt).toLocaleString() : '—')}</div>
        {health?.responseTime ? <div><span className="text-[var(--bl-text-tertiary)]">Response:</span> {health.responseTime}ms</div> : null}
      </div>
    </div>
  );
}

function getHealthTone(score: number) {
  if (score >= 85) return 'success';
  if (score >= 70) return 'info';
  if (score >= 55) return 'warning';
  return 'error';
}

function ProductCard({ product }: { product: HermesProduct }) {
  const activeTasks = getHermesTasks({ productId: product.id }).filter((task) => task.status === 'running' || task.status === 'queued' || task.status === 'blocked').length;
  const failedTasks = getHermesTasks({ productId: product.id }).filter((task) => task.status === 'failed').length;
  return (
    <div className="rounded-3xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-5 shadow-[var(--bl-shadow-sm)]">
      <div className="flex items-start justify-between gap-3">
        <div>
          <Link href={`/hermes/tasks?productId=${product.id}`} className="font-semibold text-[var(--bl-text-primary)] hover:underline">{product.name}</Link>
          <p className="mt-1 text-sm text-[var(--bl-text-secondary)]">{product.category} · {product.owner}</p>
        </div>
        <div className="flex items-center gap-2">
          <HermesInstanceBadge instanceId={product.instanceId} />
          <Badge variant={product.needsAttention ? 'warning' : 'success'}>{product.status}</Badge>
        </div>
      </div>
      <p className="mt-3 text-sm text-[var(--bl-text-secondary)]">{product.description}</p>
      <div className="mt-4 flex flex-wrap gap-2">
        {product.tags.map((tag) => <Badge key={tag} variant="neutral">{tag}</Badge>)}
      </div>
      <div className="mt-4 space-y-3 text-sm text-[var(--bl-text-secondary)]">
        <div className="flex items-center justify-between"><span>Health score</span><span className="font-medium text-[var(--bl-text-primary)]">{product.healthScore}</span></div>
        <div className="h-2 rounded-full bg-[var(--bl-surface-muted)]"><div className={`h-2 rounded-full bg-[var(--bl-${getHealthTone(product.healthScore) === 'success' ? 'success' : getHealthTone(product.healthScore) === 'info' ? 'accent' : getHealthTone(product.healthScore) === 'warning' ? 'warning' : 'danger'})]`} style={{ width: `${product.healthScore}%` }} /></div>
        <div className="flex items-center justify-between"><span>Active tasks</span><span>{activeTasks}</span></div>
        <div className="flex items-center justify-between"><span>Failed tasks</span><span>{failedTasks}</span></div>
        <div className="flex items-center justify-between"><span>Last activity</span><span>{product.lastHermesActivityAt ? new Date(product.lastHermesActivityAt).toLocaleDateString() : '—'}</span></div>
      </div>
    </div>
  );
}

export default function HermesProductsPage() {
  const [query, setQuery] = useState('');
  const [view, setView] = useState<(typeof views)[number]['key']>('all');

  // --- Live services state ---
  const [services, setServices] = useState<Service[] | null>(null);
  const [health, setHealth] = useState<Map<string, ServiceHealth>>(new Map());
  const [servicesError, setServicesError] = useState<string | null>(null);
  const [refreshing, setRefreshing] = useState(false);

  const loadServices = useCallback(async (signal?: AbortSignal) => {
    try {
      const [servicesData, healthData] = await Promise.all([api.getServices(), api.getHealth()]);
      if (signal?.aborted) return;
      setServices(servicesData);
      setHealth(new Map(healthData.map((h) => [h.serviceId, h])));
      setServicesError(null);
    } catch (err) {
      if (signal?.aborted) return;
      setServicesError(err instanceof Error ? err.message : String(err));
      setServices((prev) => prev ?? []);
    }
  }, []);

  useEffect(() => {
    const controller = new AbortController();
    loadServices(controller.signal);
    return () => controller.abort();
  }, [loadServices]);

  const refreshLive = useCallback(async () => {
    setRefreshing(true);
    try {
      await api.clearHealthCache().catch(() => undefined); // best-effort
      await loadServices();
    } finally {
      setRefreshing(false);
    }
  }, [loadServices]);

  const liveServiceCount = services?.length ?? 0;
  const liveUp = services?.filter((s) => (health.get(s.id)?.status ?? s.status) === 'up').length ?? 0;
  const liveDegraded = services?.filter((s) => (health.get(s.id)?.status ?? s.status) === 'degraded').length ?? 0;
  const liveDown = services?.filter((s) => (health.get(s.id)?.status ?? s.status) === 'down').length ?? 0;

  // --- Seed (planned) section state ---
  const { selectedInstance } = useHermesInstance();
  const products = useMemo(() => {
    return getHermesProducts(view, selectedInstance).filter((product) => {
      const haystack = [product.name, product.slug, product.category, product.owner, product.description, ...product.tags].join(' ').toLowerCase();
      return haystack.includes(query.toLowerCase().trim());
    });
  }, [query, view, selectedInstance]);

  const attentionCount = hermesProducts.filter((product) => product.needsAttention).length;
  const highPriorityCount = hermesProducts.filter((product) => product.priority === 'P0' || product.priority === 'P1').length;
  const recentCount = hermesProducts.filter((product) => product.lastHermesActivityAt && new Date(product.lastHermesActivityAt).getTime() > Date.now() - 14 * 86_400_000).length;

  return (
    <HermesShell
      title="Product Portfolio"
      description="Live services from the deployment registry on top, plus a seeded portfolio view for planned products that don't have a deployment yet."
      actions={<Button asChild><Link href="/hermes"><Orbit className="mr-2 h-4 w-4" />Back to mission control</Link></Button>}
    >
      {/* --- Live services from the real backend service registry --- */}
      <SectionCard
        title="Live services"
        subtitle="Sourced from the deployment registry (`backend/src/modules/services`) and the health module. This is the real fleet — `pnpm seed:services` populates it."
        actions={(
          <div className="flex items-center gap-2">
            <Badge variant="success">Live data</Badge>
            <Button variant="secondary" size="sm" onClick={refreshLive} disabled={refreshing}>
              <RefreshCw className={`mr-2 h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />Refresh
            </Button>
          </div>
        )}
      >
        <section className="mb-4 grid gap-3 md:grid-cols-4">
          <MetricCard label="Live services" value={liveServiceCount} tone="info" />
          <MetricCard label="Up" value={liveUp} tone="success" />
          <MetricCard label="Degraded" value={liveDegraded} tone="warning" />
          <MetricCard label="Down" value={liveDown} tone="danger" />
        </section>

        {servicesError ? (
          <p className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] p-4 text-sm text-[var(--bl-warning)]">
            Could not load services from the registry: {servicesError}
          </p>
        ) : services === null ? (
          <p className="text-sm text-[var(--bl-text-secondary)]">Loading services…</p>
        ) : services.length === 0 ? (
          <p className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] p-4 text-sm text-[var(--bl-text-secondary)]">
            No services registered yet. Use the seed action on the dashboard home page to populate the registry.
          </p>
        ) : (
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            {services.map((service) => (
              <LiveServiceCard key={service.id} service={service} health={health.get(service.id)} />
            ))}
          </div>
        )}
      </SectionCard>

      {/* --- Planned products (seed data) — kept for visual continuity --- */}
      <SectionCard
        title="Planned products (seed data)"
        subtitle="Mock product portfolio kept until manual entries for not-yet-deployed products are wired in. Not a live source."
        actions={<Badge variant="neutral">Seed</Badge>}
      >
        <section className="mb-4 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
          <MetricCard label="All planned" value={hermesProducts.length} tone="info" icon={<Sparkles className="h-5 w-5" />} />
          <MetricCard label="High priority" value={highPriorityCount} tone="warning" icon={<ShieldAlert className="h-5 w-5" />} />
          <MetricCard label="Needs attention" value={attentionCount} tone="danger" icon={<TrendingUp className="h-5 w-5" />} />
          <MetricCard label="Recently active" value={recentCount} tone="success" icon={<Rocket className="h-5 w-5" />} />
        </section>

        <div className="mb-4 grid gap-3 lg:grid-cols-[1fr_auto]">
          <Input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search planned products..." aria-label="Search planned products" />
          <div className="flex flex-wrap gap-2">
            {views.map((item) => (
              <Button key={item.key} variant={view === item.key ? 'primary' : 'secondary'} size="sm" onClick={() => setView(item.key)}>{item.label}</Button>
            ))}
          </div>
        </div>
        <div className="mb-3 flex items-center gap-2 text-sm text-[var(--bl-text-secondary)]"><Filter className="h-4 w-4" />{products.length} planned products match the current filters.</div>

        <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
          {products.map((product) => <ProductCard key={product.id} product={product} />)}
          {products.length === 0 ? <p className="text-sm text-[var(--bl-text-secondary)]">No planned products matched the current filters.</p> : null}
        </div>
      </SectionCard>
    </HermesShell>
  );
}
