'use client';

import { ChangeEvent, FormEvent, useEffect, useRef, useState } from 'react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import HlsPlayer from './media/[id]/hls-player';

type MediaStatus = {
  id: string;
  resourceId: string | null;
  filename: string;
  status: string;
  hlsPath: string | null;
  hlsUrl: string | null;
  errorMessage: string | null;
  metadata: { hlsPath?: string; processedAt?: string } | null;
  createdAt: string;
  updatedAt: string;
};

type UploadResponse = { mediaId: string; filename: string; status: string };
const terminalStates = new Set(['completed', 'failed']);

export default function MediaConsole() {
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [mediaStatus, setMediaStatus] = useState<MediaStatus | null>(null);
  const [lastUpload, setLastUpload] = useState<UploadResponse | null>(null);
  const inputRef = useRef<HTMLInputElement | null>(null);
  const mediaId = lastUpload?.mediaId;

  useEffect(() => {
    if (!mediaId || terminalStates.has(mediaStatus?.status || '')) return;
    let cancelled = false;

    async function pollStatus() {
      try {
        const response = await fetch(`/api/media/${mediaId}/status`, { cache: 'no-store' });
        const payload = await response.json();
        if (!response.ok) throw new Error(payload.error || '状态查询失败');
        if (!cancelled) setMediaStatus(payload.media);
      } catch (err) {
        if (!cancelled) setError(err instanceof Error ? err.message : '状态查询失败');
      }
    }

    pollStatus();
    const timer = window.setInterval(pollStatus, 1500);
    return () => { cancelled = true; window.clearInterval(timer); };
  }, [mediaId, mediaStatus?.status]);

  function handleFileChange(event: ChangeEvent<HTMLInputElement>) {
    setSelectedFile(event.target.files?.[0] || null);
    setError(null);
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!selectedFile) { setError('请选择一个视频文件'); return; }
    setUploading(true);
    setError(null);
    setMediaStatus(null);
    setLastUpload(null);
    const formData = new FormData();
    formData.append('file', selectedFile);

    try {
      const response = await fetch('/api/media/upload', { method: 'POST', body: formData });
      const payload = await response.json();
      if (!response.ok) throw new Error(payload.error || '上传失败');
      setLastUpload(payload.media);
      setMediaStatus({
        id: payload.media.mediaId,
        filename: payload.media.filename,
        status: payload.media.status,
        hlsPath: null,
        hlsUrl: null,
        resourceId: null,
        errorMessage: null,
        metadata: null,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      });
    } catch (err) {
      setError(err instanceof Error ? err.message : '上传失败');
    } finally {
      setUploading(false);
    }
  }

  const canUpload = Boolean(selectedFile) && !uploading;

  return (
    <main className="min-h-screen p-8 max-md:p-5">
      <section className="mx-auto max-w-6xl">
        <div className="mb-6 flex items-end justify-between gap-5 max-md:items-start">
          <div>
            <p className="mb-2 text-xs uppercase text-[hsl(var(--muted-foreground))]">EKB Media Pipeline</p>
            <h1 className="text-4xl font-semibold max-md:text-3xl">媒体处理控制台</h1>
          </div>
          <Badge>{mediaStatus?.status || 'idle'}</Badge>
        </div>

        <form className="grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 rounded-lg border bg-white p-5 max-md:grid-cols-1" onSubmit={handleSubmit}>
          <input ref={inputRef} className="hidden" type="file" accept="video/*" onChange={handleFileChange} />
          <Button variant="outline" type="button" onClick={() => inputRef.current?.click()}>选择视频</Button>
          <div className="grid min-w-0 gap-1">
            <strong className="[overflow-wrap:anywhere]">{selectedFile?.name || '未选择文件'}</strong>
            <span className="text-sm text-[hsl(var(--muted-foreground))]">{selectedFile ? `${Math.ceil(selectedFile.size / 1024)} KB` : '支持 MP4 等视频文件'}</span>
          </div>
          <Button type="submit" disabled={!canUpload}>{uploading ? '上传中' : '上传并转码'}</Button>
        </form>

        {error ? <div className="mt-4 rounded-md border border-red-300 bg-red-50 p-3 text-sm text-red-800">{error}</div> : null}

        <section className="mt-5 grid grid-cols-2 gap-5 max-md:grid-cols-1">
          <Card>
            <CardHeader><CardTitle>处理状态</CardTitle></CardHeader>
            <CardContent>
              <dl className="grid gap-3">
                {[
                  ['媒体 ID', mediaStatus?.id || '-'],
                  ['资源 ID', mediaStatus?.resourceId || '-'],
                  ['文件名', mediaStatus?.filename || selectedFile?.name || '-'],
                  ['HLS Key', mediaStatus?.hlsPath || '-'],
                  ['完成时间', mediaStatus?.metadata?.processedAt || '-'],
                  ['失败原因', mediaStatus?.errorMessage || '-'],
                ].map(([label, value]) => (
                  <div className="grid grid-cols-[100px_minmax(0,1fr)] gap-3 border-b pb-3 last:border-b-0" key={label}>
                    <dt className="text-[hsl(var(--muted-foreground))]">{label}</dt>
                    <dd className="[overflow-wrap:anywhere]">{value}</dd>
                  </div>
                ))}
              </dl>
            </CardContent>
          </Card>

          <Card>
            <CardHeader><CardTitle>播放预览</CardTitle></CardHeader>
            <CardContent className="grid gap-4">
              {mediaStatus?.hlsUrl ? (
                <>
                  <HlsPlayer src={mediaStatus.hlsUrl} />
                  <Button variant="outline" type="button" onClick={() => { window.location.href = '/media'; }}>查看媒体列表</Button>
                </>
              ) : (
                <div className="grid aspect-video w-full place-items-center rounded-md border border-dashed text-[hsl(var(--muted-foreground))]">
                  {mediaStatus?.status === 'failed' ? '处理失败' : '等待 HLS 输出'}
                </div>
              )}
            </CardContent>
          </Card>
        </section>
      </section>
    </main>
  );
}
