'use client';

import { Fragment, useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { Download, Filter, Search, ChevronDown, ChevronUp, ArrowLeftRight, Activity } from 'lucide-react';
import {
  Badge,
  Button,
  Card,
  DataTable,
  DataTableBody,
  DataTableCell,
  DataTableHead,
  DataTableHeader,
  DataTableRow,
  Input,
  Select,
} 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 {
  getHermesProductById,
  getHermesTasks,
  hermesProducts,
  type HermesPriority,
  type HermesTaskStatus,
  type HermesTaskType,
  type HermesTaskSource,
  type HermesTask,
} from '@/lib/hermes';
import {
  collectBackupEntries,
  collectCronEntries,
  collectSessionEntries,
  collectWatchdogAlerts,
  emptyTelemetryState,
  loadAllHermesTelemetry,
  telemetryForFilter,
  type HermesTelemetryState,
} from '@/lib/hermes-telemetry-client';

const statuses: Array<HermesTaskStatus | 'all'> = ['all', 'queued', 'running', 'blocked', 'completed', 'failed', 'skipped', 'cancelled'];
const priorities: Array<HermesPriority | 'all'> = ['all', 'P0', 'P1', 'P2', 'P3'];
const taskTypes: Array<HermesTaskType | 'all'> = ['all', 'build', 'deploy', 'bugfix', 'monitoring', 'audit', 'refactor', 'documentation', 'research', 'security', 'cost-optimization', 'release', 'maintenance', 'product-planning'];
const sources: Array<HermesTaskSource | 'all'> = ['all', 'manual', 'cron', 'github', 'monitoring-alert', 'email', 'cli', 'webhook', 'local-agent', 'hermes-planner'];
const sortOptions = ['newest', 'oldest', 'priority', 'status'] as const;
const pageSize = 8;

const optionize = (items: string[], allLabel: string) => items.map((item) => ({
  value: item,
  label: item === 'all' ? allLabel : item,
}));

function prettyDate(value?: string) {
  return value ? new Intl.DateTimeFormat('en', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }).format(new Date(value)) : '—';
}

function exportTasks(tasks: HermesTask[]) {
  const blob = new Blob([JSON.stringify(tasks, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `hermes-task-ledger-${new Date().toISOString().slice(0, 10)}.json`;
  a.click();
  URL.revokeObjectURL(url);
}

export default function HermesTaskLedgerPage() {
  const [query, setQuery] = useState('');
  const [status, setStatus] = useState<HermesTaskStatus | 'all'>('all');
  const [productId, setProductId] = useState<string | 'all'>('all');
  const [priority, setPriority] = useState<HermesPriority | 'all'>('all');
  const [type, setType] = useState<HermesTaskType | 'all'>('all');
  const [source, setSource] = useState<HermesTaskSource | 'all'>('all');
  const [updatedWithinDays, setUpdatedWithinDays] = useState<number | 'all'>('all');
  const [sort, setSort] = useState<(typeof sortOptions)[number]>('newest');
  const [page, setPage] = useState(1);
  const [expandedTaskId, setExpandedTaskId] = useState<string | null>(null);
  const [telemetry, setTelemetry] = useState<HermesTelemetryState>(emptyTelemetryState);
  const [telemetryError, setTelemetryError] = useState<string | null>(null);

  const { selectedInstance } = useHermesInstance();
  const tasks = useMemo(
    () => getHermesTasks({ query, status, productId, priority, type, source, instance: selectedInstance, updatedWithinDays, sort }),
    [query, status, productId, priority, type, source, selectedInstance, updatedWithinDays, sort],
  );
  const totalPages = Math.max(1, Math.ceil(tasks.length / pageSize));
  const pagedTasks = tasks.slice((page - 1) * pageSize, page * pageSize);

  const counts = useMemo(() => ({
    queued: tasks.filter((task) => task.status === 'queued').length,
    running: tasks.filter((task) => task.status === 'running').length,
    blocked: tasks.filter((task) => task.status === 'blocked').length,
    failed: tasks.filter((task) => task.status === 'failed').length,
  }), [tasks]);

  const visibleProducts = hermesProducts.slice(0, 20);
  const liveSnapshots = useMemo(() => telemetryForFilter(telemetry, selectedInstance), [telemetry, selectedInstance]);
  const liveCron = useMemo(() => collectCronEntries(telemetry, selectedInstance), [telemetry, selectedInstance]);
  const liveAlerts = useMemo(() => collectWatchdogAlerts(telemetry, selectedInstance), [telemetry, selectedInstance]);
  const liveBackups = useMemo(() => collectBackupEntries(telemetry, selectedInstance), [telemetry, selectedInstance]);
  const liveSessions = useMemo(() => collectSessionEntries(telemetry, selectedInstance), [telemetry, selectedInstance]);
  const liveActivityRows = useMemo(() => [
    ...liveSessions.map((entry) => ({
      id: `session-${entry.instanceId}-${entry.id}`,
      instanceId: entry.instanceId,
      kind: 'session',
      title: entry.displayName ? `${entry.displayName} session` : entry.sessionKey,
      detail: entry.resumePending ? 'resume pending' : entry.suspended ? 'suspended' : entry.platform ?? 'session',
      time: entry.updatedAt ?? entry.createdAt,
      tone: entry.resumePending || entry.suspended ? 'warning' as const : 'info' as const,
    })),
    ...liveCron.map((entry) => ({
      id: `cron-${entry.instanceId}-${entry.id}`,
      instanceId: entry.instanceId,
      kind: 'cron',
      title: entry.name,
      detail: entry.lastStatus ?? entry.schedule ?? 'Hermes cron entry',
      time: entry.nextRun ?? entry.lastRun,
      tone: entry.active ? 'success' as const : 'neutral' as const,
    })),
    ...liveAlerts.map((alert) => ({
      id: `alert-${alert.instanceId}-${alert.timestamp}-${alert.message}`,
      instanceId: alert.instanceId,
      kind: 'alert',
      title: alert.message,
      detail: alert.severity,
      time: alert.timestamp,
      tone: alert.severity === 'critical' ? 'error' as const : alert.severity === 'warn' ? 'warning' as const : 'info' as const,
    })),
    ...liveBackups.map((entry) => ({
      id: `backup-${entry.instanceId}-${entry.sha}`,
      instanceId: entry.instanceId,
      kind: 'backup',
      title: entry.subject,
      detail: entry.sha.slice(0, 8),
      time: entry.committedAt,
      tone: 'success' as const,
    })),
  ].sort((a, b) => new Date(b.time ?? 0).getTime() - new Date(a.time ?? 0).getTime()).slice(0, 12), [liveSessions, liveCron, liveAlerts, liveBackups]);

  useEffect(() => {
    let active = true;
    const load = async () => {
      try {
        const next = await loadAllHermesTelemetry();
        if (!active) return;
        setTelemetry(next);
        setTelemetryError(null);
      } catch (err) {
        if (!active) return;
        setTelemetryError(err instanceof Error ? err.message : String(err));
      }
    };
    void load();
    return () => {
      active = false;
    };
  }, []);

  return (
    <HermesShell
      title="Task Ledger"
      description="Searchable, filterable execution ledger for everything Hermes is doing or has done. Use this view to inspect the work queue, failure clusters, and next actions."
      actions={(
        <>
          <Button variant="secondary" onClick={() => exportTasks(tasks)}><Download className="mr-2 h-4 w-4" />Export JSON</Button>
          <Button asChild><Link href="/hermes"><ArrowLeftRight className="mr-2 h-4 w-4" />Back to overview</Link></Button>
        </>
      )}
    >
      <section className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <MetricCard label="Queued" value={counts.queued} tone="default" />
        <MetricCard label="Running" value={counts.running} tone="info" />
        <MetricCard label="Blocked" value={counts.blocked} tone="warning" />
        <MetricCard label="Failed" value={counts.failed} tone="danger" />
      </section>

      <SectionCard
        title="Live Hermes activity ledger"
        subtitle="Real cron entries, watchdog alerts, backup commits, and session totals from the telemetry endpoint. The task table below remains the planner-style seed ledger until Hermes emits task-level events."
        actions={<Badge variant={telemetryError ? 'error' : 'success'}>{telemetryError ? 'Telemetry unavailable' : 'Live telemetry'}</Badge>}
      >
        {telemetryError ? (
          <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 telemetry: {telemetryError}
          </p>
        ) : (
          <div className="grid gap-4 xl:grid-cols-[1fr_2fr]">
            <div className="grid gap-3">
              {liveSnapshots.map((snapshot) => (
                <div key={snapshot.instanceId} className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] p-4">
                  <div className="flex items-center justify-between gap-3">
                    <HermesInstanceBadge instanceId={snapshot.instanceId} />
                    <Badge variant={snapshot.sessions.status === 'up' ? 'success' : 'warning'}>{snapshot.sessions.status}</Badge>
                  </div>
                  <p className="mt-3 text-2xl font-semibold text-[var(--bl-text-primary)]">{snapshot.sessions.totalSessions}</p>
                  <p className="text-sm text-[var(--bl-text-secondary)]">{snapshot.sessions.totalMessages} session messages observed</p>
                </div>
              ))}
            </div>
            <div className="overflow-hidden rounded-2xl border border-[var(--bl-border)]">
              <table className="min-w-full divide-y divide-[var(--bl-border)] text-left text-sm">
                <thead className="bg-[var(--bl-surface-muted)] text-xs uppercase tracking-[0.18em] text-[var(--bl-text-tertiary)]">
                  <tr>
                    <th className="px-4 py-3">Artifact</th>
                    <th className="px-4 py-3">Instance</th>
                    <th className="px-4 py-3">Signal</th>
                    <th className="px-4 py-3">Time</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-[var(--bl-border)] bg-[var(--bl-surface-card)]">
                  {liveActivityRows.map((row) => (
                    <tr key={row.id}>
                      <td className="px-4 py-4">
                        <div className="flex items-start gap-2">
                          <Activity className="mt-0.5 h-4 w-4 text-[var(--bl-text-tertiary)]" />
                          <div>
                            <p className="font-medium text-[var(--bl-text-primary)]">{row.title}</p>
                            <p className="text-xs text-[var(--bl-text-secondary)]">{row.kind}</p>
                          </div>
                        </div>
                      </td>
                      <td className="px-4 py-4"><HermesInstanceBadge instanceId={row.instanceId} /></td>
                      <td className="px-4 py-4"><Badge variant={row.tone}>{row.detail}</Badge></td>
                      <td className="px-4 py-4 text-[var(--bl-text-secondary)]">{row.time ? prettyDate(row.time) : '—'}</td>
                    </tr>
                  ))}
                  {liveActivityRows.length === 0 ? (
                    <tr>
                      <td colSpan={4} className="px-4 py-10 text-center text-[var(--bl-text-secondary)]">No live activity artifacts were returned for the current instance filter.</td>
                    </tr>
                  ) : null}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </SectionCard>

      <SectionCard title="Filters" subtitle="Find work by status, product, priority, type, source, or age.">
        <div className="grid gap-3 lg:grid-cols-4 xl:grid-cols-7">
          <Input value={query} onChange={(event) => { setQuery(event.target.value); setPage(1); }} placeholder="Search tasks..." aria-label="Search tasks" className="xl:col-span-2" />
          <Select value={status} onChange={(event) => { setStatus(event.target.value as HermesTaskStatus | 'all'); setPage(1); }} options={optionize(statuses, 'All statuses')} aria-label="Status" />
          <Select value={productId} onChange={(event) => { setProductId(event.target.value); setPage(1); }} options={[{ value: 'all', label: 'All products' }, ...visibleProducts.map((product) => ({ value: product.id, label: product.name }))]} aria-label="Product" />
          <Select value={priority} onChange={(event) => { setPriority(event.target.value as HermesPriority | 'all'); setPage(1); }} options={optionize(priorities, 'All priorities')} aria-label="Priority" />
          <Select value={type} onChange={(event) => { setType(event.target.value as HermesTaskType | 'all'); setPage(1); }} options={optionize(taskTypes, 'All types')} aria-label="Type" />
          <Select value={source} onChange={(event) => { setSource(event.target.value as HermesTaskSource | 'all'); setPage(1); }} options={optionize(sources, 'All sources')} aria-label="Source" />
          <Select value={updatedWithinDays} onChange={(event) => { setUpdatedWithinDays(event.target.value === 'all' ? 'all' : Number(event.target.value)); setPage(1); }} options={[{ value: 'all', label: 'Any time' }, { value: '1', label: 'Last 24h' }, { value: '7', label: 'Last 7d' }, { value: '30', label: 'Last 30d' }]} aria-label="Updated within" />
          <Select value={sort} onChange={(event) => { setSort(event.target.value as typeof sort); setPage(1); }} options={sortOptions.map((item) => ({ value: item, label: item }))} aria-label="Sort" />
        </div>
        <div className="mt-3 flex flex-wrap gap-2 text-sm text-[var(--bl-text-secondary)]">
          <span className="inline-flex items-center gap-2 rounded-full border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] px-3 py-1"><Filter className="h-3.5 w-3.5" />{tasks.length} matches</span>
          <span className="inline-flex items-center gap-2 rounded-full border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] px-3 py-1"><Search className="h-3.5 w-3.5" />Search is applied across task titles, products, agents, and notes</span>
        </div>
      </SectionCard>

      <SectionCard title="Task table" subtitle="Click any task title to inspect the full detail view." actions={<Badge variant="neutral">Page {page} of {totalPages}</Badge>}>
        <DataTable>
              <DataTableHeader>
                <DataTableRow>
                  <DataTableHead>Task</DataTableHead>
                  <DataTableHead>Product</DataTableHead>
                  <DataTableHead>Status</DataTableHead>
                  <DataTableHead>Priority</DataTableHead>
                  <DataTableHead>Type</DataTableHead>
                  <DataTableHead>Source</DataTableHead>
                  <DataTableHead>Created</DataTableHead>
                  <DataTableHead>Duration</DataTableHead>
                  <DataTableHead className="text-right">Actions</DataTableHead>
                </DataTableRow>
              </DataTableHeader>
              <DataTableBody>
                {pagedTasks.map((task) => {
                  const product = getHermesProductById(task.productId);
                  const expanded = expandedTaskId === task.id;
                  return (
                    <Fragment key={task.id}>
                      <DataTableRow className="align-top">
                        <DataTableCell>
                          <div className="max-w-[24rem] space-y-1">
                            <Link href={`/hermes/tasks/${task.id}`} className="font-medium text-[var(--bl-text-primary)] hover:underline">{task.title}</Link>
                            <p className="line-clamp-2 text-xs leading-5 text-[var(--bl-text-secondary)]">{task.description}</p>
                          </div>
                        </DataTableCell>
                        <DataTableCell className="text-[var(--bl-text-secondary)]">
                          <div className="flex flex-wrap items-center gap-2">
                            <span>{product?.name ?? 'Unknown'}</span>
                            <HermesInstanceBadge instanceId={task.instanceId} />
                          </div>
                        </DataTableCell>
                        <DataTableCell><Badge variant={task.status === 'completed' ? 'success' : task.status === 'failed' ? 'error' : task.status === 'blocked' ? 'warning' : 'neutral'}>{task.status}</Badge></DataTableCell>
                        <DataTableCell><Badge variant={task.priority === 'P0' ? 'error' : task.priority === 'P1' ? 'warning' : 'neutral'}>{task.priority}</Badge></DataTableCell>
                        <DataTableCell className="text-[var(--bl-text-secondary)]">{task.type}</DataTableCell>
                        <DataTableCell className="text-[var(--bl-text-secondary)]">{task.source}</DataTableCell>
                        <DataTableCell className="text-[var(--bl-text-secondary)]">{prettyDate(task.createdAt)}</DataTableCell>
                        <DataTableCell className="text-[var(--bl-text-secondary)]">{task.durationMs ? `${Math.round(task.durationMs / 60000)}m` : '—'}</DataTableCell>
                        <DataTableCell className="text-right">
                          <div className="inline-flex items-center gap-2">
                            <Button variant="ghost" size="sm" onClick={() => setExpandedTaskId(expanded ? null : task.id)}>
                              {expanded ? <ChevronUp className="mr-1 h-4 w-4" /> : <ChevronDown className="mr-1 h-4 w-4" />}
                              Details
                            </Button>
                            <Button asChild variant="secondary" size="sm"><Link href={`/hermes/tasks/${task.id}`}>Open</Link></Button>
                          </div>
                        </DataTableCell>
                      </DataTableRow>
                      {expanded ? (
                        <DataTableRow key={`${task.id}-details`}>
                          <DataTableCell colSpan={9} className="bg-[var(--bl-surface-muted)]">
                            <div className="grid gap-4 lg:grid-cols-2">
                              <Card padding="sm">
                                <p className="text-xs uppercase tracking-[0.2em] text-[var(--bl-text-tertiary)]">Summary</p>
                                <p className="mt-2 text-sm text-[var(--bl-text-secondary)]">{task.summary}</p>
                                <div className="mt-3 space-y-2 text-sm text-[var(--bl-text-secondary)]">
                                  <div>Current step: {task.currentStep ?? 'n/a'}</div>
                                  <div>Last action: {task.lastAction ?? 'n/a'}</div>
                                  <div>Next action: {task.nextAction ?? 'n/a'}</div>
                                </div>
                              </Card>
                              <Card padding="sm">
                                <p className="text-xs uppercase tracking-[0.2em] text-[var(--bl-text-tertiary)]">Signals</p>
                                <div className="mt-3 flex flex-wrap gap-2">
                                  {task.tags.map((tag) => <Badge key={tag} variant="neutral">{tag}</Badge>)}
                                </div>
                                <div className="mt-4 space-y-2 text-sm text-[var(--bl-text-secondary)]">
                                  <div>Retry count: {task.retryCount}</div>
                                  <div>Assigned agent: {task.assignedAgent}</div>
                                  <div>Started: {prettyDate(task.startedAt)}</div>
                                  <div>Completed: {prettyDate(task.completedAt)}</div>
                                </div>
                              </Card>
                            </div>
                          </DataTableCell>
                        </DataTableRow>
                      ) : null}
                    </Fragment>
                  );
                })}
                {pagedTasks.length === 0 ? (
                  <DataTableRow>
                    <DataTableCell colSpan={9} className="px-4 py-10 text-center text-[var(--bl-text-secondary)]">No tasks matched the current filters.</DataTableCell>
                  </DataTableRow>
                ) : null}
              </DataTableBody>
        </DataTable>
        <div className="mt-4 flex flex-wrap items-center justify-between gap-3">
          <p className="text-sm text-[var(--bl-text-secondary)]">Showing {pagedTasks.length} of {tasks.length} filtered tasks.</p>
          <div className="flex items-center gap-2">
            <Button variant="secondary" size="sm" disabled={page <= 1} onClick={() => setPage((value) => Math.max(1, value - 1))}>Prev</Button>
            <Button variant="secondary" size="sm" disabled={page >= totalPages} onClick={() => setPage((value) => Math.min(totalPages, value + 1))}>Next</Button>
          </div>
        </div>
      </SectionCard>
    </HermesShell>
  );
}
