import React, { useState } from 'react';
import { Button, Input, Modal, Space, Upload, message } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import type { UploadFile } from 'antd/es/upload/interface';
import { createPrivatePortraitAsset, uploadPrivatePortraitImage, uploadPrivatePortraitVideo } from '../../../api';

const MIN_PRIVATE_VIDEO_DURATION = 2;
const MAX_PRIVATE_VIDEO_DURATION = 15;

interface Props {
  projectId: string;
  open: boolean;
  onClose: () => void;
  onSuccess: () => void;
}

const guessAssetType = (file?: File | null): 'Image' | 'Video' => {
  if (!file) return 'Image';
  if (file.type.startsWith('video/')) return 'Video';
  const name = file.name.toLowerCase();
  if (/\.(mp4|mov|webm|m4v|avi|mkv)$/.test(name)) return 'Video';
  return 'Image';
};

const getVideoDuration = (file: File): Promise<number | null> => {
  return new Promise((resolve) => {
    if (!file.type.startsWith('video/')) {
      resolve(null);
      return;
    }
    const url = URL.createObjectURL(file);
    const video = document.createElement('video');
    video.preload = 'metadata';
    video.onloadedmetadata = () => {
      const duration = Number.isFinite(video.duration) ? video.duration : null;
      URL.revokeObjectURL(url);
      resolve(duration);
    };
    video.onerror = () => {
      URL.revokeObjectURL(url);
      resolve(null);
    };
    video.src = url;
  });
};

const validatePrivateVideoDuration = (duration: number | null): duration is number => {
  if (duration == null || !Number.isFinite(duration) || duration <= 0) {
    message.error('无法读取视频秒数，请检查视频文件是否损坏');
    return false;
  }
  if (duration < MIN_PRIVATE_VIDEO_DURATION) {
    message.error(`视频素材最短不能少于 ${MIN_PRIVATE_VIDEO_DURATION} 秒`);
    return false;
  }
  if (duration > MAX_PRIVATE_VIDEO_DURATION) {
    message.error(`视频素材最长不能超过 ${MAX_PRIVATE_VIDEO_DURATION} 秒`);
    return false;
  }
  return true;
};

const PrivatePortraitAssetUpload: React.FC<Props> = ({ projectId, open, onClose, onSuccess }) => {
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [name, setName] = useState('');
  const [loading, setLoading] = useState(false);

  const reset = () => {
    setFileList([]);
    setName('');
  };

  const handleSubmit = async () => {
    const file = fileList[0]?.originFileObj as File | undefined;
    if (!file) {
      message.warning('请先选择图片或视频素材');
      return;
    }
    const assetType = guessAssetType(file);
    if (assetType === 'Image' && !file.type.startsWith('image/')) {
      message.error('仅支持图片或视频素材');
      return;
    }

    setLoading(true);
    try {
      const videoDuration = assetType === 'Video' ? await getVideoDuration(file) : null;
      if (assetType === 'Video' && !validatePrivateVideoDuration(videoDuration)) {
        return;
      }

      const uploaded = assetType === 'Video' ? await uploadPrivatePortraitVideo(file, videoDuration || undefined) : await uploadPrivatePortraitImage(file);
      await createPrivatePortraitAsset(projectId, {
        url: uploaded.url,
        assetType,
        name: name.trim() || file.name,
        videoDuration: uploaded.duration_seconds ?? videoDuration,
        fileSize: uploaded.file_size_bytes ?? file.size,
        mimeType: file.type || null,
        uploadResourceId: uploaded.resource_id || null,
      });
      message.success(assetType === 'Video' ? '视频素材已提交入库，处理中' : '图片素材已提交入库，处理中');
      reset();
      onSuccess();
      onClose();
    } catch (e: any) {
      message.error(e?.message || '上传素材失败');
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      title="上传真人素材"
      open={open}
      onCancel={onClose}
      onOk={handleSubmit}
      confirmLoading={loading}
      okText="提交入库"
      destroyOnHidden
    >
      <Space direction="vertical" style={{ width: '100%' }} size={12}>
        <Input value={name} onChange={(e) => setName(e.target.value)} placeholder="素材名称，默认使用文件名" maxLength={256} />
        <Upload
          accept="image/*,video/*"
          maxCount={1}
          fileList={fileList}
          beforeUpload={() => false}
          onChange={({ fileList }) => setFileList(fileList)}
          listType="picture"
        >
          <Button icon={<UploadOutlined />}>选择图片或视频</Button>
        </Upload>
        <div style={{ color: '#64748b', fontSize: 12 }}>
          当前开放图片和视频，音频暂不接入。视频素材必须在 {MIN_PRIVATE_VIDEO_DURATION}~{MAX_PRIVATE_VIDEO_DURATION} 秒内；入库后会经过火山真人一致性校验，Active 后才可用于 AI 创作。
        </div>
      </Space>
    </Modal>
  );
};

export default PrivatePortraitAssetUpload;
