'use client';

import React, { useEffect, useMemo, useState } from 'react';
import { AlertCircle, Bot, Braces, ChevronDown, Loader2, MessageSquare, RefreshCw, TerminalSquare } from 'lucide-react';

import { getChatLogs } from '@/lib/api';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import type { ChatLogEvent, ChatLogSession } from '@/types';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { containedJsonTextClass } from '@/lib/text-wrapping';

function eventLabel(event: ChatLogEvent): string {
  return event.event_type || event.role || 'event';
}

function eventIcon(event: ChatLogEvent) {
  if (event.event_type === 'llm_request_snapshotted') return Braces;
  if (event.role === 'assistant') return Bot;
  if (event.role === 'tool') return TerminalSquare;
  return MessageSquare;
}

function formatPayload(value: unknown): string {
  if (value === null || value === undefined || value === '') return '';
  if (typeof value === 'string') return value;
  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
}

function eventBody(event: ChatLogEvent): string {
  const content = event.content?.trim();
  if (content) return content;
  return formatPayload(event.event_payload);
}

function timestampLabel(value?: string | null): string {
  if (!value) return '';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString();
}

export default function LogsPage() {
  const { locale } = useAppI18n();
  const [sessions, setSessions] = useState<ChatLogSession[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [expandedRuns, setExpandedRuns] = useState<Set<string>>(() => new Set());

  const runs = useMemo(
    () =>
      sessions.flatMap((session) =>
        session.runs.map((run) => ({
          ...run,
          sessionTitle: session.title || session.session_id,
        }))
      ),
    [sessions]
  );

  const loadLogs = async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await getChatLogs(80);
      setSessions(data.sessions || []);
      const firstRun = data.sessions?.[0]?.runs?.[0]?.run_id;
      if (firstRun) {
        setExpandedRuns((current) => (current.size ? current : new Set([firstRun])));
      }
    } catch (err: any) {
      setError(err.message || pickAppText(locale, '读取日志失败', 'Failed to load logs'));
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadLogs();
  }, []);

  const toggleRun = (runId: string) => {
    setExpandedRuns((current) => {
      const next = new Set(current);
      if (next.has(runId)) next.delete(runId);
      else next.add(runId);
      return next;
    });
  };

  return (
    <div className="mx-auto max-w-7xl p-6 space-y-6">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <h1 className="text-2xl font-bold">{pickAppText(locale, '运行日志', 'Runtime Logs')}</h1>
          <p className="mt-1 text-sm text-muted-foreground">
            {pickAppText(
              locale,
              '按每一次用户输入分组，查看 LLM 请求、回复、工具结果和隐藏运行快照。',
              'Grouped by each user input, with LLM requests, responses, tool results, and hidden runtime snapshots.'
            )}
          </p>
        </div>
        <Button onClick={loadLogs} variant="outline" size="sm" disabled={loading}>
          {loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <RefreshCw className="mr-2 h-4 w-4" />}
          {pickAppText(locale, '刷新', 'Refresh')}
        </Button>
      </div>

      {error ? (
        <Card className="border-destructive">
          <CardContent className="flex items-start gap-3 pt-6 text-destructive">
            <AlertCircle className="mt-0.5 h-5 w-5" />
            <div>
              <p className="text-sm font-medium">{pickAppText(locale, '无法读取日志', 'Unable to load logs')}</p>
              <p className="mt-1 text-sm text-muted-foreground">{error}</p>
            </div>
          </CardContent>
        </Card>
      ) : null}

      {loading && !runs.length ? (
        <div className="flex items-center justify-center py-20">
          <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
        </div>
      ) : null}

      {!loading && !runs.length && !error ? (
        <Card>
          <CardContent className="py-12 text-center text-sm text-muted-foreground">
            {pickAppText(locale, '还没有可展示的运行日志。', 'No runtime logs are available yet.')}
          </CardContent>
        </Card>
      ) : null}

      <div className="space-y-3">
        {runs.map((run) => {
          const expanded = expandedRuns.has(run.run_id);
          return (
            <Card key={`${run.session_id}:${run.run_id}`} className="overflow-hidden">
              <button
                type="button"
                onClick={() => toggleRun(run.run_id)}
                className="flex w-full items-start justify-between gap-4 border-b px-5 py-4 text-left transition-colors hover:bg-muted/40"
              >
                <span className="min-w-0 space-y-2">
                  <span className="flex flex-wrap items-center gap-2">
                    <Badge variant={run.task_mode ? 'default' : 'secondary'}>
                      {run.task_mode ? 'Task' : 'Chat'}
                    </Badge>
                    {run.source ? <Badge variant="outline">{run.source}</Badge> : null}
                    {run.attempt_index ? <Badge variant="outline">attempt {run.attempt_index}</Badge> : null}
                    <span className="text-xs text-muted-foreground">{timestampLabel(run.started_at)}</span>
                  </span>
                  <span className="block truncate text-sm font-semibold text-foreground">
                    {run.user_input || run.title || run.run_id}
                  </span>
                  <span className="block truncate text-xs text-muted-foreground">
                    {run.sessionTitle} · {run.run_id}
                  </span>
                </span>
                <ChevronDown className={`mt-1 h-4 w-4 shrink-0 text-muted-foreground transition-transform ${expanded ? 'rotate-180' : ''}`} />
              </button>

              {expanded ? (
                <CardContent className="space-y-3 p-5">
                  {run.events.map((event, index) => {
                    const Icon = eventIcon(event);
                    const body = eventBody(event);
                    return (
                      <div
                        key={`${event.message_id ?? index}:${event.event_type}`}
                        className="min-w-0 max-w-full overflow-hidden rounded-lg border border-border bg-background"
                      >
                        <div className="flex flex-wrap items-center justify-between gap-2 border-b px-3 py-2">
                          <div className="flex min-w-0 items-center gap-2">
                            <Icon className="h-4 w-4 shrink-0 text-muted-foreground" />
                            <span className="truncate text-sm font-medium">{eventLabel(event)}</span>
                            <Badge variant={event.context_visible ? 'secondary' : 'outline'}>
                              {event.context_visible ? 'visible' : 'hidden'}
                            </Badge>
                            {event.tool_name ? <Badge variant="outline">{event.tool_name}</Badge> : null}
                          </div>
                          <span className="text-xs text-muted-foreground">{timestampLabel(event.timestamp)}</span>
                        </div>
                        <pre className={`max-h-[520px] overflow-auto p-3 text-xs leading-5 text-foreground ${containedJsonTextClass}`}>
                          {body || formatPayload(event)}
                        </pre>
                      </div>
                    );
                  })}
                </CardContent>
              ) : null}
            </Card>
          );
        })}
      </div>
    </div>
  );
}
