'use client';

import { useEffect, useRef, useState } from 'react';
import { apiWebSocketURL } from '@/lib/api';
import { cn } from '@/lib/cn';
import type { BuildEvent, BuildStatus } from '@bmm/types';
import { StatusPill } from './status-pill';

export interface StreamingLogsProps {
  buildId: string;
  onDone?: (status: BuildStatus, publicUrl: string | null) => void;
  className?: string;
}

interface LogLine {
  level: 'info' | 'warn' | 'error';
  message: string;
  at: string;
}

export function StreamingLogs({ buildId, onDone, className }: StreamingLogsProps) {
  const [logs, setLogs] = useState<LogLine[]>([]);
  const [status, setStatus] = useState<BuildStatus>('queued');
  const [connected, setConnected] = useState(false);
  const scrollRef = useRef<HTMLDivElement>(null);
  const onDoneRef = useRef(onDone);
  onDoneRef.current = onDone;

  useEffect(() => {
    const url = apiWebSocketURL(`/v1/builds/${buildId}/stream`);
    const ws = new WebSocket(url);
    ws.onopen = () => setConnected(true);
    ws.onclose = () => setConnected(false);
    ws.onmessage = (ev) => {
      try {
        const evt = JSON.parse(ev.data) as BuildEvent;
        if (evt.type === 'log') {
          setLogs((prev) => [...prev, { level: evt.level, message: evt.message, at: evt.at }]);
        } else if (evt.type === 'status') {
          setStatus(evt.status);
        } else if (evt.type === 'done') {
          setStatus(evt.status);
          onDoneRef.current?.(evt.status, evt.publicUrl);
        } else if (evt.type === 'error') {
          setLogs((prev) => [...prev, { level: 'error', message: evt.message, at: evt.at }]);
        }
      } catch {}
    };
    return () => ws.close();
  }, [buildId]);

  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [logs.length]);

  return (
    <div className={cn('panel', className)}>
      <div className="flex items-center justify-between border-b border-[--color-border] px-3 py-2">
        <div className="flex items-center gap-2">
          <span className="mono text-[11px] uppercase tracking-wider text-[--color-fg-subtle]">
            build.log
          </span>
          <StatusPill status={status} />
        </div>
        <span className="mono text-[10.5px] text-[--color-fg-subtle]">
          {connected ? 'ws · connected' : 'ws · …'}
        </span>
      </div>
      <div ref={scrollRef} className="mono max-h-80 overflow-y-auto p-3 text-[12px] leading-relaxed">
        {logs.length === 0 && (
          <div className="text-[--color-fg-subtle]">Waiting for build events…</div>
        )}
        {logs.map((l, i) => (
          <div
            key={i}
            className={cn(
              'whitespace-pre-wrap',
              l.level === 'error' && 'text-[--color-danger]',
              l.level === 'warn' && 'text-[--color-warn]',
              l.level === 'info' && 'text-[--color-fg-muted]',
            )}
          >
            <span className="text-[--color-fg-subtle]">
              {new Date(l.at).toLocaleTimeString()}
            </span>
            {'  '}
            {l.message}
          </div>
        ))}
      </div>
    </div>
  );
}
