import { useState, useMemo, useEffect, useCallback } from 'react';
import {
  Layout,
  Typography,
  Button,
  Input,
  Select,
  Radio,
  Card,
  Table,
  Modal,
  Form,
  Upload,
  Drawer,
  Descriptions,
  Space,
  Timeline,
  Empty,
  message,
  List,
  Alert
} from 'antd';
import {
  UploadOutlined,
  DownloadOutlined,
  DeleteOutlined,
  FileOutlined
} from '@ant-design/icons';
import { useApi } from '@/hooks/useApi';
import { DocumentsService } from '@/services/documents';
import { ProductionsService } from '@/services/productions';
import { VenueManagementService } from '@/services/venueManagement';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';

interface Document {
  id: string;
  production_id: string | null;
  venue_id: string | null;
  uploaded_by_user_id: string;
  title: string;
  description: string | null;
  document_type: string | null;
  file_url: string;
  file_size_bytes: number | null;
  mime_type: string | null;
  created_at: string;
  updated_at: string;
}

interface DocumentDetail extends Document {
  production: {
    id: string;
    title: string;
  } | null;
  venue: {
    id: string;
    name: string;
  } | null;
  uploaded_by_user: {
    id: string;
    first_name: string;
    last_name: string;
  } | null;
}

interface Production {
  id: string;
  title: string;
}

interface Venue {
  id: string;
  name: string;
}

const DocumentsListPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const { currentUser } = useAppContext();

  const [documents, setDocuments] = useState<Document[]>([]);
  const [productions, setProductions] = useState<Production[]>([]);
  const [venues, setVenues] = useState<Venue[]>([]);
  const [searchText, setSearchText] = useState<string>('');
  const [filterType, setFilterType] = useState<string>('');
  const [filterProduction, setFilterProduction] = useState<string>('');
  const [filterVenue, setFilterVenue] = useState<string>('');
  const [viewMode, setViewMode] = useState<string>('grid');
  const [uploadModalVisible, setUploadModalVisible] = useState<boolean>(false);
  const [detailDrawerVisible, setDetailDrawerVisible] = useState<boolean>(false);
  const [selectedDocumentId, setSelectedDocumentId] = useState<string>('');
  const [selectedDocumentDetail, setSelectedDocumentDetail] = useState<DocumentDetail | null>(null);
  const [loading, setLoading] = useState<boolean>(false);

  const [uploadForm] = Form.useForm();

  const { data: documentsData, loading: documentsLoading, error: documentsError, execute: fetchDocuments } = useApi(DocumentsService.list);
  const { data: productionsData, loading: productionsLoading, error: productionsError, execute: fetchProductions } = useApi(ProductionsService.list);
  const { data: venuesData, loading: venuesLoading, error: venuesError, execute: fetchVenues } = useApi(VenueManagementService.list);
  const { execute: fetchDocumentDetail } = useApi(DocumentsService.getDetails);

  useEffect(() => {
    void fetchDocuments({ limit: 100 });
    void fetchProductions({ limit: 100 });
    void fetchVenues({ limit: 100 });
  }, [fetchDocuments, fetchProductions, fetchVenues]);

  useEffect(() => {
    if (documentsData) {
      setDocuments(documentsData as Document[]);
    }
  }, [documentsData]);

  useEffect(() => {
    if (productionsData) {
      setProductions(productionsData as Production[]);
    }
  }, [productionsData]);

  useEffect(() => {
    if (venuesData) {
      setVenues(venuesData as Venue[]);
    }
  }, [venuesData]);

  useEffect(() => {
    if (documentsError) {
      const { message: errorMessage } = parseError(documentsError);
      messageApi.error(errorMessage);
    }
  }, [documentsError, messageApi]);

  useEffect(() => {
    if (productionsError) {
      const { message: errorMessage } = parseError(productionsError);
      messageApi.error(errorMessage);
    }
  }, [productionsError, messageApi]);

  useEffect(() => {
    if (venuesError) {
      const { message: errorMessage } = parseError(venuesError);
      messageApi.error(errorMessage);
    }
  }, [venuesError, messageApi]);

  const filteredDocuments = useMemo(() => {
    return documents.filter(d => {
      const matchesSearch = !searchText || d.title.toLowerCase().includes(searchText.toLowerCase());
      const matchesType = !filterType || d.document_type === filterType;
      const matchesProduction = !filterProduction || d.production_id === filterProduction;
      const matchesVenue = !filterVenue || d.venue_id === filterVenue;
      return matchesSearch && matchesType && matchesProduction && matchesVenue;
    });
  }, [documents, searchText, filterType, filterProduction, filterVenue]);

  const productionOptions = useMemo(() => {
    return productions.map(p => ({ label: p.title, value: p.id }));
  }, [productions]);

  const venueOptions = useMemo(() => {
    return venues.map(v => ({ label: v.name, value: v.id }));
  }, [venues]);

  const handleOpenUploadModal = useCallback(() => {
    setUploadModalVisible(true);
  }, []);

  const handleCloseUploadModal = useCallback(() => {
    setUploadModalVisible(false);
    uploadForm.resetFields();
  }, [uploadForm]);

  const handleUploadSubmit = useCallback(async () => {
    try {
      const values = await uploadForm.validateFields();
      setLoading(true);
      await DocumentsService.create({
        title: values.title,
        description: values.description,
        document_type: values.document_type,
        file_url: values.file_url,
        production_id: values.production_id,
        venue_id: values.venue_id,
        uploaded_by_user_id: currentUser?.id || ''
      });
      messageApi.success('Document uploaded successfully');
      setUploadModalVisible(false);
      uploadForm.resetFields();
      await fetchDocuments({ limit: 100 });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, [uploadForm, currentUser, messageApi, fetchDocuments]);

  const handleDocumentSelect = useCallback(async (documentId: string) => {
    setSelectedDocumentId(documentId);
    setDetailDrawerVisible(true);
    try {
      const result = await fetchDocumentDetail(documentId);
      if (result?.data) {
        setSelectedDocumentDetail(result.data as DocumentDetail);
      }
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [fetchDocumentDetail, messageApi]);

  const handleCloseDetailDrawer = useCallback(() => {
    setDetailDrawerVisible(false);
    setSelectedDocumentDetail(null);
  }, []);

  const handleDeleteDocument = useCallback(() => {
    Modal.confirm({
      title: 'Move to Trash',
      content: 'Are you sure you want to move this document to trash?',
      okText: 'Yes',
      cancelText: 'No',
      onOk: async () => {
        try {
          await DocumentsService.delete(selectedDocumentId);
          messageApi.success('Document moved to trash');
          setDetailDrawerVisible(false);
          await fetchDocuments({ limit: 100 });
        } catch (e) {
          const { message: errorMessage } = parseError(e);
          messageApi.error(errorMessage);
        }
      }
    });
  }, [selectedDocumentId, messageApi, fetchDocuments]);

  const handleDownloadDocument = useCallback(() => {
    if (selectedDocumentDetail?.file_url) {
      const link = document.createElement('a');
      link.href = selectedDocumentDetail.file_url;
      link.download = selectedDocumentDetail.title;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  }, [selectedDocumentDetail]);

  const formatFileSize = (bytes: number | null): string => {
    if (!bytes) return 'N/A';
    const kb = bytes / 1024;
    if (kb < 1024) return `${kb.toFixed(2)} KB`;
    const mb = kb / 1024;
    return `${mb.toFixed(2)} MB`;
  };

  const formatDate = (dateString: string): string => {
    return new Date(dateString).toLocaleDateString();
  };

  const tableColumns = useMemo(() => [
    {
      title: 'Name',
      dataIndex: 'title',
      key: 'title',
      ellipsis: true
    },
    {
      title: 'Type',
      dataIndex: 'document_type',
      key: 'document_type',
      render: (type: string | null) => type || 'N/A'
    },
    {
      title: 'Upload Date',
      dataIndex: 'created_at',
      key: 'created_at',
      render: (date: string) => formatDate(date)
    },
    {
      title: 'Size',
      dataIndex: 'file_size_bytes',
      key: 'file_size_bytes',
      render: (size: number | null) => formatFileSize(size)
    }
  ], []);

  return (
    <Layout style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', background: '#f5f5f5' }}>
      {contextHolder}
      <div style={{ padding: '0 24px', maxWidth: '1400px', margin: '0 auto', width: '100%' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '24px 0' }}>
          <Typography.Title level={2} style={{ margin: 0 }}>
            Documents
          </Typography.Title>
          <Button
            type="primary"
            icon={<UploadOutlined />}
            size="large"
            onClick={handleOpenUploadModal}
          >
            Upload Document
          </Button>
        </div>

        <div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', alignItems: 'center', marginBottom: '24px' }}>
          <Input.Search
            placeholder="Search by filename..."
            allowClear
            style={{ width: 280 }}
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
          />
          <Select
            placeholder="All Types"
            allowClear
            style={{ width: 160 }}
            value={filterType || undefined}
            onChange={(value) => setFilterType(value || '')}
            options={[
              { label: 'Script', value: 'SCRIPT' },
              { label: 'Contract', value: 'CONTRACT' },
              { label: 'Rider', value: 'RIDER' },
              { label: 'Schedule', value: 'SCHEDULE' },
              { label: 'Budget', value: 'BUDGET' },
              { label: 'Other', value: 'OTHER' }
            ]}
          />
          <Select
            placeholder="All Productions"
            allowClear
            style={{ width: 200 }}
            value={filterProduction || undefined}
            onChange={(value) => setFilterProduction(value || '')}
            options={productionOptions}
          />
          <Select
            placeholder="All Venues"
            allowClear
            style={{ width: 180 }}
            value={filterVenue || undefined}
            onChange={(value) => setFilterVenue(value || '')}
            options={venueOptions}
          />
          <Radio.Group
            optionType="button"
            buttonStyle="solid"
            style={{ marginLeft: 'auto' }}
            value={viewMode}
            onChange={(e) => setViewMode(e.target.value)}
            options={[
              { label: 'Grid', value: 'grid' },
              { label: 'List', value: 'list' }
            ]}
          />
        </div>

        {documentsError && (
          <Alert
            message="Error loading documents"
            description={parseError(documentsError).message}
            type="error"
            showIcon
            style={{ marginBottom: 16 }}
          />
        )}

        {viewMode === 'grid' ? (
          <List
            grid={{ gutter: 16, xs: 1, sm: 2, md: 3, lg: 4 }}
            dataSource={filteredDocuments}
            loading={documentsLoading || loading}
            locale={{ emptyText: <Empty description="No documents found" /> }}
            renderItem={(item) => (
              <List.Item>
                <Card
                  hoverable
                  size="small"
                  style={{ borderRadius: '8px' }}
                  onClick={() => handleDocumentSelect(item.id)}
                >
                  <div style={{ fontSize: '32px', textAlign: 'center', padding: '16px 0', color: '#6366f1' }}>
                    <FileOutlined />
                  </div>
                  <Typography.Text strong ellipsis style={{ display: 'block' }}>
                    {item.title}
                  </Typography.Text>
                  <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                    {item.document_type || 'N/A'} • {formatFileSize(item.file_size_bytes)}
                  </Typography.Text>
                </Card>
              </List.Item>
            )}
          />
        ) : (
          <Table
            columns={tableColumns}
            dataSource={filteredDocuments}
            rowKey="id"
            pagination={{ pageSize: 20 }}
            loading={documentsLoading || loading}
            onRow={(record) => ({
              onClick: () => handleDocumentSelect(record.id)
            })}
            locale={{ emptyText: <Empty description="No documents found" /> }}
          />
        )}
      </div>

      <Modal
        title="Upload Document"
        open={uploadModalVisible}
        onCancel={handleCloseUploadModal}
        width={640}
        destroyOnClose
        footer={null}
      >
        <Form
          form={uploadForm}
          layout="vertical"
          onFinish={handleUploadSubmit}
        >
          <Form.Item
            name="file_url"
            label="File"
            rules={[{ required: true, message: 'File is required' }]}
          >
            <Upload.Dragger
              name="file"
              multiple={false}
              accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg"
              beforeUpload={() => false}
            >
              <p className="ant-upload-drag-icon">
                <UploadOutlined />
              </p>
              <p className="ant-upload-text">Click or drag file to this area to upload</p>
              <p className="ant-upload-hint">Maximum file size: 50MB</p>
            </Upload.Dragger>
          </Form.Item>

          <Form.Item
            name="title"
            label="Name"
            rules={[{ required: true, message: 'Document name is required' }]}
          >
            <Input />
          </Form.Item>

          <Form.Item name="description" label="Description">
            <Input.TextArea rows={3} />
          </Form.Item>

          <Form.Item name="document_type" label="Type">
            <Select
              options={[
                { label: 'Script', value: 'SCRIPT' },
                { label: 'Contract', value: 'CONTRACT' },
                { label: 'Rider', value: 'RIDER' },
                { label: 'Schedule', value: 'SCHEDULE' },
                { label: 'Budget', value: 'BUDGET' },
                { label: 'Other', value: 'OTHER' }
              ]}
            />
          </Form.Item>

          <Form.Item name="production_id" label="Associated Production">
            <Select options={productionOptions} allowClear />
          </Form.Item>

          <Form.Item name="venue_id" label="Associated Venue">
            <Select options={venueOptions} allowClear />
          </Form.Item>

          <Form.Item>
            <Button type="primary" htmlType="submit" block loading={loading}>
              Upload
            </Button>
          </Form.Item>
        </Form>
      </Modal>

      <Drawer
        title="Document Details"
        open={detailDrawerVisible}
        onClose={handleCloseDetailDrawer}
        width={560}
        placement="right"
        destroyOnClose
      >
        {selectedDocumentDetail && (
          <>
            <div style={{
              background: '#fafafa',
              borderRadius: '8px',
              padding: '24px',
              textAlign: 'center',
              marginBottom: '16px',
              minHeight: '200px',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center'
            }}>
              <FileOutlined style={{ fontSize: '64px', color: '#6366f1' }} />
            </div>

            <Descriptions column={1} size="small" bordered style={{ marginBottom: '16px' }}>
              <Descriptions.Item label="Title">{selectedDocumentDetail.title}</Descriptions.Item>
              <Descriptions.Item label="Type">{selectedDocumentDetail.document_type || 'N/A'}</Descriptions.Item>
              <Descriptions.Item label="Description">{selectedDocumentDetail.description || 'N/A'}</Descriptions.Item>
              <Descriptions.Item label="File Size">{formatFileSize(selectedDocumentDetail.file_size_bytes)}</Descriptions.Item>
              <Descriptions.Item label="Uploaded">{formatDate(selectedDocumentDetail.created_at)}</Descriptions.Item>
              <Descriptions.Item label="Production">{selectedDocumentDetail.production?.title || 'N/A'}</Descriptions.Item>
              <Descriptions.Item label="Venue">{selectedDocumentDetail.venue?.name || 'N/A'}</Descriptions.Item>
              <Descriptions.Item label="Uploaded By">
                {selectedDocumentDetail.uploaded_by_user
                  ? `${selectedDocumentDetail.uploaded_by_user.first_name} ${selectedDocumentDetail.uploaded_by_user.last_name}`
                  : 'N/A'}
              </Descriptions.Item>
            </Descriptions>

            <Space direction="vertical" style={{ width: '100%', marginTop: '16px' }}>
              <Button
                type="primary"
                icon={<DownloadOutlined />}
                block
                onClick={handleDownloadDocument}
              >
                Download
              </Button>
              <Button icon={<UploadOutlined />} block>
                Upload New Version
              </Button>
              <Button
                danger
                icon={<DeleteOutlined />}
                block
                onClick={handleDeleteDocument}
              >
                Move to Trash
              </Button>
            </Space>

            <div style={{ marginTop: '24px' }}>
              <Typography.Title level={5}>Version History</Typography.Title>
              <Timeline
                items={[
                  { children: 'Current version uploaded' }
                ]}
              />
            </div>
          </>
        )}
      </Drawer>
    </Layout>
  );
};

export default DocumentsListPage;