import { useState, useCallback } from 'react';
import { Upload, Button, List, Typography, Space, Tooltip } from 'antd';
import { showSuccess, showError } from '@/lib/errorHandling';
import {
  UploadOutlined,
  FileOutlined,
  FilePdfOutlined,
  FileImageOutlined,
  DeleteOutlined,
  EyeOutlined,
  DownloadOutlined,
} from '@ant-design/icons';
import type { UploadFile, UploadProps } from 'antd/es/upload/interface';
import { spacing } from '@/styles/designTokens';

const { Text } = Typography;

export interface Attachment {
  id: string;
  fileName: string;
  fileType: string;
  fileSize: number;
  uploadedAt: string;
  uploadedBy?: string;
  url?: string;
}

interface AttachmentUploadProps {
  /** List of existing attachments */
  attachments?: Attachment[];
  /** Callback when files are uploaded */
  onUpload?: (files: File[]) => Promise<Attachment[]>;
  /** Callback when an attachment is removed */
  onRemove?: (attachmentId: string) => Promise<void>;
  /** Callback when an attachment is viewed */
  onView?: (attachment: Attachment) => void;
  /** Maximum number of attachments allowed */
  maxCount?: number;
  /** Maximum file size in bytes (default 10MB) */
  maxFileSize?: number;
  /** Allowed file types */
  accept?: string;
  /** Whether the component is disabled */
  disabled?: boolean;
  /** Whether uploads are required (shows warning if empty) */
  required?: boolean;
  /** Compact mode for inline display */
  compact?: boolean;
}

const formatFileSize = (bytes: number): string => {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
};

const getFileIcon = (fileType: string) => {
  if (fileType.includes('pdf')) return <FilePdfOutlined style={{ color: '#ff4d4f' }} />;
  if (fileType.includes('image')) return <FileImageOutlined style={{ color: '#1890ff' }} />;
  return <FileOutlined style={{ color: '#8c8c8c' }} />;
};

/**
 * Bilag (Document/Attachment) upload component.
 * Supports drag-drop, multiple file upload, and preview.
 * Required by Bogforingsloven § 6 for document retention.
 */
export function AttachmentUpload({
  attachments = [],
  onUpload,
  onRemove,
  onView,
  maxCount = 10,
  maxFileSize = 10 * 1024 * 1024, // 10MB default
  accept = '.pdf,.png,.jpg,.jpeg,.gif,.doc,.docx,.xls,.xlsx',
  disabled = false,
  required = false,
  compact = false,
}: AttachmentUploadProps) {
  const [uploading, setUploading] = useState(false);
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const handleUpload = useCallback(async () => {
    if (!onUpload || fileList.length === 0) return;

    setUploading(true);
    try {
      const files = fileList
        .filter((f) => f.originFileObj)
        .map((f) => f.originFileObj as File);

      await onUpload(files);
      setFileList([]);
      showSuccess(`${files.length} bilag uploadet`);
    } catch (error) {
      showError('Fejl ved upload af bilag');
      console.error('Upload error:', error);
    } finally {
      setUploading(false);
    }
  }, [fileList, onUpload]);

  const handleRemove = useCallback(
    async (attachment: Attachment) => {
      if (!onRemove) return;

      try {
        await onRemove(attachment.id);
        showSuccess('Bilag slettet');
      } catch (error) {
        showError('Fejl ved sletning af bilag');
        console.error('Remove error:', error);
      }
    },
    [onRemove]
  );

  const uploadProps: UploadProps = {
    multiple: true,
    accept,
    disabled: disabled || attachments.length >= maxCount,
    fileList,
    beforeUpload: (file) => {
      // Validate file size
      if (file.size > maxFileSize) {
        showError(`Filen "${file.name}" er for stor (max ${formatFileSize(maxFileSize)})`);
        return Upload.LIST_IGNORE;
      }

      // Check max count
      if (attachments.length + fileList.length >= maxCount) {
        showError(`Maksimalt ${maxCount} bilag tilladt`);
        return Upload.LIST_IGNORE;
      }

      return false; // Don't auto-upload
    },
    onChange: ({ fileList: newFileList }) => {
      setFileList(newFileList);
    },
    onRemove: (file) => {
      setFileList((prev) => prev.filter((f) => f.uid !== file.uid));
    },
  };

  if (compact) {
    return (
      <Space size="small" wrap>
        <Upload {...uploadProps} showUploadList={false}>
          <Button
            icon={<UploadOutlined />}
            size="small"
            disabled={disabled || attachments.length >= maxCount}
            aria-label="Upload bilag"
          >
            Bilag ({attachments.length})
          </Button>
        </Upload>
        {fileList.length > 0 && (
          <Button
            type="primary"
            size="small"
            loading={uploading}
            onClick={handleUpload}
            disabled={disabled}
          >
            Upload {fileList.length}
          </Button>
        )}
      </Space>
    );
  }

  return (
    <div>
      {/* Upload area */}
      <Upload.Dragger
        {...uploadProps}
        style={{ marginBottom: attachments.length > 0 || fileList.length > 0 ? spacing.md : 0 }}
      >
        <p className="ant-upload-drag-icon">
          <UploadOutlined style={{ fontSize: 32, color: '#1890ff' }} />
        </p>
        <p className="ant-upload-text">
          Klik eller traek filer hertil for at uploade bilag
        </p>
        <p className="ant-upload-hint">
          Understotter PDF, billeder og Office-dokumenter (max {formatFileSize(maxFileSize)})
        </p>
      </Upload.Dragger>

      {/* Pending uploads */}
      {fileList.length > 0 && (
        <div style={{ marginBottom: spacing.md }}>
          <Space style={{ marginBottom: spacing.sm }}>
            <Text type="secondary">{fileList.length} fil(er) klar til upload</Text>
            <Button
              type="primary"
              size="small"
              loading={uploading}
              onClick={handleUpload}
              disabled={disabled}
            >
              Upload alle
            </Button>
          </Space>
        </div>
      )}

      {/* Required warning */}
      {required && attachments.length === 0 && fileList.length === 0 && (
        <Text type="warning" style={{ display: 'block', marginBottom: spacing.sm }}>
          Bilag er pakraevet iht. Bogforingsloven § 6
        </Text>
      )}

      {/* Existing attachments */}
      {attachments.length > 0 && (
        <List
          size="small"
          dataSource={attachments}
          renderItem={(attachment) => (
            <List.Item
              style={{ padding: `${spacing.xs}px 0` }}
              actions={[
                onView && (
                  <Tooltip title="Se bilag" key="view">
                    <Button
                      type="text"
                      size="small"
                      icon={<EyeOutlined />}
                      onClick={() => onView(attachment)}
                      aria-label={`Se ${attachment.fileName}`}
                    />
                  </Tooltip>
                ),
                attachment.url && (
                  <Tooltip title="Download" key="download">
                    <Button
                      type="text"
                      size="small"
                      icon={<DownloadOutlined />}
                      href={attachment.url}
                      target="_blank"
                      aria-label={`Download ${attachment.fileName}`}
                    />
                  </Tooltip>
                ),
                onRemove && !disabled && (
                  <Tooltip title="Slet bilag" key="remove">
                    <Button
                      type="text"
                      size="small"
                      danger
                      icon={<DeleteOutlined />}
                      onClick={() => handleRemove(attachment)}
                      aria-label={`Slet ${attachment.fileName}`}
                    />
                  </Tooltip>
                ),
              ].filter(Boolean)}
            >
              <List.Item.Meta
                avatar={getFileIcon(attachment.fileType)}
                title={
                  <Text ellipsis style={{ maxWidth: 200 }}>
                    {attachment.fileName}
                  </Text>
                }
                description={
                  <Text type="secondary" style={{ fontSize: 12 }}>
                    {formatFileSize(attachment.fileSize)}
                    {attachment.uploadedAt && ` - ${new Date(attachment.uploadedAt).toLocaleDateString('da-DK')}`}
                  </Text>
                }
              />
            </List.Item>
          )}
        />
      )}

      {/* Max count info */}
      {attachments.length > 0 && (
        <Text type="secondary" style={{ fontSize: 12, display: 'block', marginTop: spacing.xs }}>
          {attachments.length} af {maxCount} bilag
        </Text>
      )}
    </div>
  );
}

export default AttachmentUpload;
