'use client';

import { useState, useMemo } from 'react';
import { useParams } from 'next/navigation';
import { BookOpen, Search } from 'lucide-react';

import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { useBreadcrumbHint } from '@/hooks/use-breadcrumb-hint';
import { ERROR_CODES } from '@/lib/error-codes';

/**
 * Error-code reference page surfaced inside the admin section so an
 * admin investigating a captured error_events row can flip to this
 * tab, look up the code the user reported, and read the canonical
 * plain-language meaning + status code without leaving the app.
 *
 * Pulls directly from `src/lib/error-codes.ts` so it stays in sync
 * automatically - adding an entry to the registry adds a row here.
 */
export default function ErrorCodeReferencePage() {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const [search, setSearch] = useState('');

  // Smart-back target: send the user back to the error inspector, not
  // the generic Administration page URL-derivation would land on.
  useBreadcrumbHint(
    portSlug
      ? {
          parents: [{ label: 'Error inspector', href: `/${portSlug}/admin/errors` }],
          current: 'Error code reference',
        }
      : null,
  );

  const entries = useMemo(() => {
    const all = Object.entries(ERROR_CODES) as Array<
      [string, (typeof ERROR_CODES)[keyof typeof ERROR_CODES]]
    >;
    if (!search.trim()) return all;
    const q = search.trim().toLowerCase();
    return all.filter(
      ([code, def]) => code.toLowerCase().includes(q) || def.userMessage.toLowerCase().includes(q),
    );
  }, [search]);

  // Group by domain prefix (the part before the first underscore) so
  // the table reads naturally - Expenses, Berths, Storage, etc.
  const grouped = useMemo(() => {
    const groups = new Map<string, typeof entries>();
    for (const entry of entries) {
      const prefix = entry[0].split('_')[0] ?? 'OTHER';
      const bucket = groups.get(prefix) ?? [];
      bucket.push(entry);
      groups.set(prefix, bucket);
    }
    return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b));
  }, [entries]);

  return (
    <div className="space-y-4">
      <div className="flex items-start justify-between gap-4 flex-wrap">
        <div>
          <h1 className="text-2xl font-bold flex items-center gap-2">
            <BookOpen className="h-5 w-5" /> Error code reference
          </h1>
          <p className="text-muted-foreground text-sm mt-1">
            Every error code the platform can return, with its HTTP status and the plain-language
            message a user sees. Codes are stable identifiers - once shipped, they never get
            renamed.
          </p>
        </div>
      </div>

      <div className="relative max-w-md">
        <Search className="pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
        <Input
          placeholder="Search code or message…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="pl-8"
        />
      </div>

      {grouped.length === 0 ? (
        <Card>
          <CardContent className="py-12 text-center text-sm text-muted-foreground">
            No codes match &quot;{search}&quot;.
          </CardContent>
        </Card>
      ) : (
        <div className="space-y-4">
          {grouped.map(([prefix, items]) => (
            <Card key={prefix}>
              <CardHeader>
                <CardTitle className="text-sm font-medium uppercase tracking-wider text-muted-foreground">
                  {prefix}
                </CardTitle>
              </CardHeader>
              <CardContent className="divide-y">
                {items.map(([code, def]) => (
                  <div key={code} className="flex items-start gap-3 py-3 first:pt-0 last:pb-0">
                    <Badge
                      variant="outline"
                      className={
                        def.status >= 500
                          ? 'border-destructive/40 text-destructive'
                          : def.status >= 400
                            ? 'border-amber-300 text-amber-800'
                            : 'border-muted'
                      }
                    >
                      {def.status}
                    </Badge>
                    <div className="flex-1 min-w-0">
                      <p className="font-mono text-xs font-semibold">{code}</p>
                      <p className="text-sm mt-0.5">{def.userMessage}</p>
                      {'hint' in def && typeof def.hint === 'string' && (
                        <p className="text-xs text-muted-foreground mt-0.5">{def.hint}</p>
                      )}
                    </div>
                  </div>
                ))}
              </CardContent>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}
