import React from 'react';
import {
  Button,
  Empty,
  Popconfirm,
  Space,
  Table,
  Tag,
  Tooltip,
  Upload,
} from 'antd';
import {
  CheckOutlined,
  FileTextOutlined,
  StopOutlined,
  UploadOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';

const RENTAL_FIELDS = {
  classroomId: 'classroomId',
  lesseeOrganizationId: 'lesseeOrganizationId',
  startDate: 'startDate',
  endDate: 'endDate',
  dailyRate: 'dailyRate',
  totalAmount: 'totalAmount',
} as const;

export interface RentalTableProps {
  data: any[];
  loading: boolean;
  classrooms: any[];
  organizations: any[];
  canPurgeRental: boolean;
  hasPermission: (permission: string) => boolean;
  onSaveCell: (record: any, field: string, value: unknown) => Promise<void> | void;
  onEdit: (record: any) => void;
  onAction: (id: number, action: 'cancel' | 'end') => void;
  onArchive: (id: number) => void;
  onPurge: (id: number, name: string) => void;
  onDownloadContract: (id: number, filename?: string) => void;
  onDeleteContract: (id: number) => void;
  onUploadContract: (id: number, formData: FormData) => Promise<unknown>;
}

export const RentalTable: React.FC<RentalTableProps> = ({
  data,
  loading,
  classrooms,
  organizations,
  canPurgeRental,
  hasPermission,
  onSaveCell,
  onEdit,
  onAction,
  onArchive,
  onPurge,
  onDownloadContract,
  onDeleteContract,
  onUploadContract,
}) => {
  const EditableRentalCell = <R extends { id: number; effectiveStatus?: string }>({
    value,
    field,
    record,
    editor,
    min,
    required,
    options,
    children,
  }: {
    value: unknown;
    field: string;
    record: R;
    editor?: React.ComponentProps<typeof EditableCell>['editor'];
    min?: number;
    required?: boolean;
    options?: Array<{ value: string | number; label: string }>;
    children?: React.ReactNode;
  }) => (
    <EditableCell
      value={value}
      editor={editor}
      min={min}
      required={required}
      options={options}
      permission="rental:edit"
      disabled={record.effectiveStatus !== 'active'}
      onSave={async (next) => {
        await onSaveCell(record, field, next);
      }}
    >
      {children ?? String(value ?? '-')}
    </EditableCell>
  );

  const columns = [
    {
      title: '教室',
      width: 120,
      dataIndex: 'classroom',
      render: (c: any, r: any) => (
        <EditableRentalCell
          value={r.classroomId}
          field={RENTAL_FIELDS.classroomId}
          record={r}
          editor="select"
          options={classrooms
            .filter((item) => item.status !== 'archived')
            .map((item) => ({
              value: item.id,
              label: item.building ? `${item.building} · ${item.name}` : item.name,
            }))}
          required
        >
          {c ? (
            <span>
              {c.building ? `${c.building} · ` : ''}
              {c.name}
            </span>
          ) : (
            '-'
          )}
        </EditableRentalCell>
      ),
    },
    {
      title: '承租机构',
      width: 100,
      dataIndex: 'lesseeOrganization',
      render: (t: any, r: any) => (
        <EditableRentalCell
          value={r.lesseeOrganizationId}
          field={RENTAL_FIELDS.lesseeOrganizationId}
          record={r}
          editor="select"
          options={organizations
            .filter((item) => item.status !== 'archived')
            .map((item) => ({ value: item.id, label: item.name }))}
          required
        >
          {t ? (
            <Tag
              color={t.color}
              style={{ background: t.color, color: '#fff', borderColor: t.color }}
            >
              {t.name}
            </Tag>
          ) : (
            '-'
          )}
        </EditableRentalCell>
      ),
    },
    {
      title: '开始日期',
      dataIndex: 'startDate',
      width: 110,
      render: (v: string, r: any) => (
        <EditableRentalCell value={v} field={RENTAL_FIELDS.startDate} record={r} editor="date" required>
          {v}
        </EditableRentalCell>
      ),
    },
    {
      title: '结束日期',
      dataIndex: 'endDate',
      width: 110,
      render: (v: string, r: any) => (
        <EditableRentalCell value={v} field={RENTAL_FIELDS.endDate} record={r} editor="date" required>
          {v}
        </EditableRentalCell>
      ),
    },
    {
      title: '时长',
      width: 80,
      render: (_: any, r: any) => {
        const d = dayjs(r.endDate).diff(dayjs(r.startDate), 'day') + 1;
        return `${d}天`;
      },
    },
    {
      title: '日租金',
      dataIndex: 'dailyRate',
      width: 100,
      render: (v: any, r: any) => (
        <EditableRentalCell value={v} field={RENTAL_FIELDS.dailyRate} record={r} editor="money" min={0.01}>
          {v ? `¥${v}` : '-'}
        </EditableRentalCell>
      ),
    },
    {
      title: '总额',
      dataIndex: 'totalAmount',
      width: 100,
      render: (v: any, r: any) => (
        <EditableRentalCell value={v} field={RENTAL_FIELDS.totalAmount} record={r} editor="money" min={0.01}>
          {v ? `¥${v}` : '-'}
        </EditableRentalCell>
      ),
    },
    {
      title: '状态',
      dataIndex: 'effectiveStatus',
      width: 90,
      render: (status: string) => {
        const config: Record<string, { text: string; color: string }> = {
          active: { text: '进行中', color: 'green' },
          ended: { text: '已结束', color: 'default' },
          cancelled: { text: '已取消', color: 'red' },
        };
        return <Tag color={config[status]?.color}>{config[status]?.text || status}</Tag>;
      },
    },
    {
      title: '合同',
      width: 120,
      dataIndex: 'contractPath',
      render: (v: string, r: any) =>
        v ? (
          <Space>
            <Tooltip title={r.contractOriginalName}>
              <Button
                size="small"
                icon={<FileTextOutlined />}
                onClick={() => onDownloadContract(r.id, r.contractOriginalName)}
              >
                下载
              </Button>
            </Tooltip>
            {hasPermission('rental:edit') ? (
              <Popconfirm title="移除合同文件？" onConfirm={() => onDeleteContract(r.id)}>
                <Button size="small" danger icon={<StopOutlined />} aria-label="移除合同文件" />
              </Popconfirm>
            ) : null}
          </Space>
        ) : hasPermission('rental:edit') ? (
          <Upload
            accept="application/pdf"
            showUploadList={false}
            customRequest={async ({ file, onSuccess, onError }: any) => {
              if (file.size > 10 * 1024 * 1024) {
                message.error('文件不能超过 10MB');
                onError?.(new Error('size'));
                return;
              }
              const formData = new FormData();
              formData.append('file', file);
              try {
                await onUploadContract(r.id, formData);
                message.success('合同已上传');
                onSuccess?.({});
              } catch (e) {
                onError?.(e as Error);
              }
            }}
          >
            <Button size="small" icon={<UploadOutlined />}>
              上传PDF
            </Button>
          </Upload>
        ) : (
          '-'
        ),
    },
    {
      title: '操作',
      width: 150,
      render: (_: any, record: any) => (
        <Space>
          {record.effectiveStatus === 'active' && (
            <>
              <PermissionButton permission="rental:edit" size="small" onClick={() => onEdit(record)}>
                编辑
              </PermissionButton>
              <Popconfirm title="确定取消该租赁？" onConfirm={() => onAction(record.id, 'cancel')}>
                <PermissionButton
                  permission="rental:edit"
                  size="small"
                  danger
                  icon={<StopOutlined />}
                >
                  取消
                </PermissionButton>
              </Popconfirm>
              {!dayjs(record.startDate).isAfter(dayjs(), 'day') && (
                <Popconfirm title="确定今天结束该租赁？" onConfirm={() => onAction(record.id, 'end')}>
                  <PermissionButton permission="rental:edit" size="small" icon={<CheckOutlined />}>
                    结束
                  </PermissionButton>
                </Popconfirm>
              )}
            </>
          )}
          {record.effectiveStatus !== 'active' && (
            <Popconfirm
              title="确定归档该租赁订单？合同文件会保留。"
              onConfirm={() => onArchive(record.id)}
            >
              <PermissionButton permission="rental:delete" size="small" danger>
                归档
              </PermissionButton>
            </Popconfirm>
          )}
          {record.status === 'cancelled' && canPurgeRental ? (
            <Button
              size="small"
              danger
              type="link"
              onClick={() => onPurge(record.id, record.lesseeOrganization?.name || `订单${record.id}`)}
            >
              删除
            </Button>
          ) : null}
        </Space>
      ),
    },
  ];

  return (
    <Table
      columns={columns}
      dataSource={data}
      rowKey="id"
      loading={loading}
      locale={{ emptyText: <Empty description="暂无数据" /> }}
      pagination={{
        defaultPageSize: 15,
        showSizeChanger: true,
        pageSizeOptions: [15, 30, 50, 100],
        showTotal: (total) => `共 ${total} 条`,
      }}
      scroll={{ x: 1200 }}
    />
  );
};
