import React, { useState } from 'react';
import { App, Button, Popconfirm, Space, Table, Upload } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { EyeOutlined, InboxOutlined, UploadOutlined } from '@ant-design/icons';
import api from '../../api';
import { message } from '../../ui/app-message';
import { useApiMutation } from '../../hooks/useApiMutation';
import { usePermission } from '../../hooks/usePermission';
import { getErrorMessage } from '../../utils/error';
import { ATTACHMENT_CATEGORY_OPTIONS, formatFileSize } from './shared';
import type { AttachmentRecord, TabProps } from './shared';

export const AttachmentsTab: React.FC<TabProps & { data: AttachmentRecord[] }> = ({
  data,
  studentId,
}) => {
  const { modal } = App.useApp();
  const { hasPermission } = usePermission();
  const canPurgeArchive = hasPermission('archive:purge');
  const [uploading, setUploading] = useState(false);

  const deleteAttachmentMutation = useApiMutation(
    async (attachmentId: number) => api.delete(`/archive/attachments/${attachmentId}`),
    { invalidate: [['archive', studentId]] },
  );
  const purgeAttachmentMutation = useApiMutation(
    async (id: number) => api.delete(`/archive/attachments/${id}/permanent`),
    { invalidate: [['archive', studentId]] },
  );
  const uploadAttachmentMutation = useApiMutation(
    async (formData: FormData) =>
      api.post(`/archive/${studentId}/attachments`, formData),
    { invalidate: [['archive', studentId]] },
  );

  const handleDelete = async (attachmentId: number) => {
    try {
      await deleteAttachmentMutation.mutateAsync(attachmentId);
      message.success('已归档');
    } catch {
      // 错误提示由 useApiMutation 统一处理
    }
  };

  const handlePurge = (record: AttachmentRecord) => {
    modal.confirm({
      title: `永久删除附件「${record.fileName}」？`,
      content: '删除后不可恢复，磁盘上的附件文件将被清除。确定继续？',
      okText: '永久删除',
      okButtonProps: { danger: true },
      cancelText: '取消',
      onOk: async () => {
        try {
          await purgeAttachmentMutation.mutateAsync(record.id);
          message.success('已永久删除（不可恢复）');
        } catch {
          // 错误提示由 useApiMutation 统一处理
        }
      },
    });
  };

  const columns: ColumnsType<AttachmentRecord> = [
    {
      title: '类别',
      dataIndex: 'category',
      render: (v: string) => ATTACHMENT_CATEGORY_OPTIONS.find((o) => o.value === v)?.label || v,
    },
    { title: '文件名', dataIndex: 'fileName' },
    { title: '大小', dataIndex: 'fileSize', render: formatFileSize },
    {
      title: '操作',
      render: (_: unknown, record: AttachmentRecord) => (
        <Space>
          <Button
            size="small"
            icon={<EyeOutlined />}
            onClick={async () => {
              try {
                const blob = await api.get<Blob>(`/archive/${studentId}/attachments/${record.id}`, {
                  responseType: 'blob',
                });
                const url = URL.createObjectURL(blob);
                window.open(url, '_blank');
                setTimeout(() => URL.revokeObjectURL(url), 60_000);
              } catch (e: unknown) {
                message.error(getErrorMessage(e, '查看失败'));
              }
            }}
          >
            查看
          </Button>
          {hasPermission('student:edit') && record.status !== 'archived' ? (
            <Popconfirm title="确定归档该附件？" onConfirm={() => handleDelete(record.id)}>
              <Button size="small" danger icon={<InboxOutlined />}>
                归档
              </Button>
            </Popconfirm>
          ) : null}
          {record.status === 'archived' && canPurgeArchive ? (
            <Button size="small" danger type="link" onClick={() => handlePurge(record)}>
              删除
            </Button>
          ) : null}
        </Space>
      ),
    },
  ];

  return (
    <div>
      {hasPermission('student:edit') ? (
        <Upload
          showUploadList={false}
          customRequest={async (options) => {
            const formData = new FormData();
            formData.append(
              'file',
              options.file instanceof File
                ? options.file
                : new File([options.file as Blob], 'attachment'),
            );
            setUploading(true);
            try {
              await uploadAttachmentMutation.mutateAsync(formData);
              message.success('上传成功');
              options.onSuccess?.({});
            } catch (e) {
              options.onError?.(e instanceof Error ? e : new Error('上传失败'));
            } finally {
              setUploading(false);
            }
          }}
        >
          <Button icon={<UploadOutlined />} loading={uploading}>
            上传附件
          </Button>
        </Upload>
      ) : null}
      <Table<AttachmentRecord>
        columns={columns}
        dataSource={data}
        rowKey="id"
        rowClassName={(record) => (record.status === 'archived' ? 'archived-row' : '')}
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50],
        }}
        style={{ marginTop: 16 }}
      />
    </div>
  );
};
