import { useState } from 'react';
import {
  Drawer,
  Upload,
  Form,
  Input,
  Progress,
  Alert,
  Space,
  Typography,
  List,
  Tag,
  Button,
  Grid,
} from 'antd';
import { InboxOutlined, CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons';
import type { UploadFile } from 'antd/es/upload/interface';
import { mediaApi } from '@/lib/media-api';
import { getErrorMessage } from '@/utils/getErrorMessage';

const { Dragger } = Upload;
const { Text } = Typography;

interface UploadVideoDrawerProps {
  open: boolean;
  onClose: () => void;
  onSuccess: () => void;
}

interface UploadResult {
  filename: string;
  success: boolean;
  error?: string;
}

export default function UploadVideoDrawer({ open, onClose, onSuccess }: UploadVideoDrawerProps) {
  const [form] = Form.useForm();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [results, setResults] = useState<UploadResult[]>([]);
  const [showResults, setShowResults] = useState(false);

  const maxFileSize = 10 * 1024 * 1024 * 1024; // 10GB

  const handleClose = () => {
    if (!uploading) {
      form.resetFields();
      setFileList([]);
      setResults([]);
      setShowResults(false);
      setUploadProgress(0);
      onClose();
    }
  };

  const beforeUpload = (file: File) => {
    // Validate file size
    if (file.size > maxFileSize) {
      return Upload.LIST_IGNORE;
    }

    // Validate file type
    const validTypes = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/x-matroska', 'video/webm', 'video/x-m4v', 'video/x-flv'];
    const validExtensions = ['.mp4', '.mov', '.avi', '.mkv', '.webm', '.m4v', '.flv'];
    const ext = file.name.toLowerCase().match(/\.[^.]+$/)?.[0];

    if (!validTypes.includes(file.type) && !validExtensions.includes(ext || '')) {
      return Upload.LIST_IGNORE;
    }

    return false; // Prevent auto-upload
  };

  const handleUpload = async () => {
    if (fileList.length === 0) {
      return;
    }

    setUploading(true);
    setShowResults(false);
    setResults([]);
    setUploadProgress(0);

    const uploadResults: UploadResult[] = [];
    let completed = 0;

    // Upload files sequentially
    for (const file of fileList) {
      try {
        const formData = new FormData();
        formData.append('file', file.originFileObj as File);

        // Add metadata for single file uploads
        if (fileList.length === 1) {
          const values = form.getFieldsValue();
          if (values.title) formData.append('title', values.title);
          if (values.producer) formData.append('producer', values.producer);
          if (values.creator) formData.append('creator', values.creator);
        }

        await mediaApi.post('/videos/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
          onUploadProgress: (progressEvent) => {
            if (progressEvent.total) {
              const fileProgress = (progressEvent.loaded / progressEvent.total) * 100;
              const totalProgress = ((completed + fileProgress / 100) / fileList.length) * 100;
              setUploadProgress(Math.round(totalProgress));
            }
          },
        });

        uploadResults.push({
          filename: file.name,
          success: true,
        });
      } catch (error: unknown) {
        uploadResults.push({
          filename: file.name,
          success: false,
          error: getErrorMessage(error, 'Upload failed'),
        });
      }

      completed++;
      setUploadProgress(Math.round((completed / fileList.length) * 100));
    }

    setResults(uploadResults);
    setShowResults(true);
    setUploading(false);

    // Auto-close and refresh if all successful
    const allSuccess = uploadResults.every((r) => r.success);
    if (allSuccess) {
      setTimeout(() => {
        onSuccess();
        handleClose();
      }, 1500);
    }
  };

  const successCount = results.filter((r) => r.success).length;
  const failCount = results.length - successCount;

  return (
    <Drawer
      title="Upload Videos"
      open={open}
      onClose={handleClose}
      placement="right"
      width={isMobile ? '100%' : 520}
      mask={false}
      destroyOnClose
      closable={!uploading}
      styles={{
        wrapper: { top: 64, height: 'calc(100vh - 64px)' },
        body: { padding: 24, overflowY: 'auto' },
      }}
      extra={
        <Space>
          <Button onClick={handleClose} disabled={uploading}>
            Cancel
          </Button>
          <Button
            type="primary"
            onClick={handleUpload}
            disabled={fileList.length === 0 || uploading}
            loading={uploading}
          >
            {uploading ? 'Uploading...' : 'Upload'}
          </Button>
        </Space>
      }
    >
      <Space direction="vertical" size="large" style={{ width: '100%' }}>
        {!showResults && (
          <>
            <Dragger
              multiple
              fileList={fileList}
              onChange={({ fileList: newFileList }) => setFileList(newFileList)}
              beforeUpload={beforeUpload}
              accept="video/*,.mp4,.mov,.avi,.mkv,.webm,.m4v,.flv"
              disabled={uploading}
              showUploadList={{ showRemoveIcon: !uploading }}
            >
              <p className="ant-upload-drag-icon">
                <InboxOutlined />
              </p>
              <p className="ant-upload-text">Click or drag video files to this area to upload</p>
              <p className="ant-upload-hint">
                Support for single or bulk upload. Maximum file size: 10GB per file.
                <br />
                Accepted formats: MP4, MOV, AVI, MKV, WebM, M4V, FLV
              </p>
            </Dragger>

            {fileList.length === 1 && (
              <Form form={form} layout="vertical">
                <Alert
                  message="Optional Metadata"
                  description="Add metadata for this video (optional)"
                  type="info"
                  showIcon
                  style={{ marginBottom: 16 }}
                />
                <Form.Item label="Title" name="title">
                  <Input placeholder="Video title (defaults to filename)" />
                </Form.Item>
                <Form.Item label="Producer" name="producer">
                  <Input placeholder="Producer name" />
                </Form.Item>
                <Form.Item label="Creator" name="creator">
                  <Input placeholder="Creator name" />
                </Form.Item>
              </Form>
            )}

            {fileList.length > 1 && (
              <Alert
                message={`${fileList.length} files selected for batch upload`}
                description="Metadata fields are not available for batch uploads. Titles will default to filenames."
                type="info"
                showIcon
              />
            )}
          </>
        )}

        {uploading && (
          <Space direction="vertical" size="small" style={{ width: '100%' }}>
            <Text>
              Uploading {fileList.length} file(s)... This may take a while for large files.
            </Text>
            <Progress percent={uploadProgress} status="active" />
          </Space>
        )}

        {showResults && (
          <Space direction="vertical" size="middle" style={{ width: '100%' }}>
            <Alert
              message={`Upload Complete: ${successCount} succeeded, ${failCount} failed`}
              type={failCount === 0 ? 'success' : 'warning'}
              showIcon
            />
            <List
              size="small"
              bordered
              dataSource={results}
              renderItem={(result) => (
                <List.Item>
                  <Space style={{ width: '100%', justifyContent: 'space-between' }}>
                    <Text ellipsis style={{ maxWidth: 340 }}>
                      {result.filename}
                    </Text>
                    {result.success ? (
                      <Tag icon={<CheckCircleOutlined />} color="success">
                        Success
                      </Tag>
                    ) : (
                      <Tag icon={<CloseCircleOutlined />} color="error" title={result.error}>
                        Failed
                      </Tag>
                    )}
                  </Space>
                  {result.error && (
                    <div style={{ marginTop: 4 }}>
                      <Text type="danger" style={{ fontSize: 12 }}>
                        {result.error}
                      </Text>
                    </div>
                  )}
                </List.Item>
              )}
            />
          </Space>
        )}
      </Space>
    </Drawer>
  );
}
