'use client';

import { useState } from 'react';
import { FoxFileUpload } from '@fox/core/components/fox-file-upload';
import { FoxHelperText } from '@fox/core/components/fox-helper-text';
import {
  FILE_MODULE,
  MAX_STREAM_UPLOAD_BYTES,
  allowedExtensions,
  fileModuleAccept,
  isAllowedFileExtension,
} from '@/lib/domain/file-module';

const UPLOAD_ENDPOINT = `/contents/upload?module=${FILE_MODULE.vodContent.id}`;

interface ContentVideoFieldProps {
  defaultFileId?: string | null;
}

/**
 * 영상 콘텐츠 — 고르는 즉시 스트리밍 라우트로 올리고 파일 ID만 폼에 싣는다.
 *
 * 영상은 Server Action의 multipart 한도(10MB)를 넘기 때문에 폼 제출에 파일을 실을 수 없다.
 * 업로드가 끝나기 전에 저장하면 영상 없이 저장되므로 그동안은 `videoUploading`을 실어 보내
 * Server Action이 막게 한다.
 */
export function ContentVideoField({ defaultFileId }: ContentVideoFieldProps) {
  const [fileId, setFileId] = useState(defaultFileId ?? '');
  const [isUploading, setIsUploading] = useState(false);
  const [error, setError] = useState('');

  async function upload(picked: File[]) {
    const file = picked[0];
    if (!file) {
      return;
    }

    setError('');

    if (!isAllowedFileExtension(FILE_MODULE.vodContent, file.name)) {
      setError(
        `${allowedExtensions(FILE_MODULE.vodContent).join(', ')} 파일만 올릴 수 있습니다.`
      );
      return;
    }
    if (file.size > MAX_STREAM_UPLOAD_BYTES) {
      setError(
        `${Math.floor(MAX_STREAM_UPLOAD_BYTES / 1_000_000)}MB 이하만 올릴 수 있습니다.`
      );
      return;
    }

    const body = new FormData();
    body.set('file', file);

    setIsUploading(true);
    try {
      const response = await fetch(UPLOAD_ENDPOINT, { method: 'POST', body });
      const payload = (await response.json()) as { id?: string; message?: string };
      if (!response.ok || !payload.id) {
        setError(payload.message ?? '영상을 업로드하지 못했습니다.');
        return;
      }
      setFileId(payload.id);
    } catch {
      setError('영상을 업로드하지 못했습니다.');
    } finally {
      setIsUploading(false);
    }
  }

  return (
    <>
      <FoxFileUpload
        mode="default"
        accept={fileModuleAccept(FILE_MODULE.vodContent)}
        selectLabel="파일선택"
        placeholder="파일을 선택해 주세요."
        disabled={isUploading}
        onSelect={upload}
        onRemove={() => setFileId('')}
      />
      <input type="hidden" name="videoFileId" value={fileId} />
      {isUploading && <input type="hidden" name="videoUploading" value="1" />}

      {isUploading && (
        <FoxHelperText type="information" message="영상을 올리는 중입니다…" />
      )}
      {error && <FoxHelperText type="danger" message={error} />}
    </>
  );
}
