import { useRef, useState, useEffect } from 'react';
import { useIntl } from '@umijs/max';
import { PageContainer, ProTable, ModalForm, ProFormText, ProFormSelect, ProFormDatePicker, ProFormDigit } from '@ant-design/pro-components';
import type { ProColumns, ActionType, ProFormInstance } from '@ant-design/pro-components';
import { Button, Popconfirm, message, Space, Row, Col, Divider, Radio, Upload, Form } from 'antd';
import type { UploadFile, UploadChangeParam } from 'antd';
import { PlusOutlined, UploadOutlined, LinkOutlined, InboxOutlined } from '@ant-design/icons';
import {
  listAssetCustody,
  createAssetCustody,
  updateAssetCustody,
  deleteAssetCustody,
  listAssets,
} from '@/services/admin/api';
import { getApiErrorMessage } from '@/utils';
import { getAccessToken } from '@/services/auth/tokenManager';

const { Dragger } = Upload;

const deleteUploadedFile = async (url: string) => {
  try {
    await fetch(`/api/admin/upload?path=${encodeURIComponent(url)}`, {
      method: 'DELETE',
      headers: { Authorization: `Bearer ${getAccessToken() || ''}` },
    });
  } catch {
    // silent — cleanup failure is non-critical
  }
};

const isEpochDate = (v: any) => !v || String(v).startsWith('1970-01-01');

const AssetCustodyPage: React.FC = () => {
  const intl = useIntl();
  const actionRef = useRef<ActionType>();
  const searchFormRef = useRef<ProFormInstance>();
  const searchTimer = useRef<ReturnType<typeof setTimeout>>();
  const [modalOpen, setModalOpen] = useState(false);
  const [editRecord, setEditRecord] = useState<Partial<AdminAPI.AssetCustody> | null>(null);
  const [assetMap, setAssetMap] = useState<Record<number, string>>({});

  const handleValuesChange = () => {
    clearTimeout(searchTimer.current);
    searchTimer.current = setTimeout(() => searchFormRef.current?.submit(), 500);
  };
  const [assetOptions, setAssetOptions] = useState<{ label: string; value: number }[]>([]);
  const [urlMode, setUrlMode] = useState<'link' | 'upload'>('link');
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploadedUrl, setUploadedUrl] = useState<string>('');
  const savedRef = useRef(false);

  useEffect(() => {
    listAssets({ pageSize: 100 }).then((res) => {
      if (res.data) {
        const map: Record<number, string> = {};
        const opts: { label: string; value: number }[] = [];
        res.data.forEach((a) => {
          map[a.id] = a.name || a.asset_code;
          opts.push({ label: `${a.name || a.asset_code} (ID: ${a.id})`, value: a.id });
        });
        setAssetMap(map);
        setAssetOptions(opts);
      }
    });
  }, []);

  const t = (id: string) => intl.formatMessage({ id });

  const resetUpload = () => {
    setFileList([]);
    setUploadedUrl('');
  };

  const openCreate = () => {
    setEditRecord(null);
    setUrlMode('link');
    resetUpload();
    savedRef.current = false;
    setModalOpen(true);
  };

  const openEdit = (record: AdminAPI.AssetCustody) => {
    setEditRecord(record);
    setUrlMode('link');
    resetUpload();
    savedRef.current = false;
    setModalOpen(true);
  };

  const handleUploadChange = ({ file, fileList: newList }: UploadChangeParam) => {
    setFileList(newList);
    if (file.status === 'done') {
      const url = file.response?.data?.url;
      if (url) {
        setUploadedUrl(url);
        message.success(t('pages.admin.auditReports.uploadSuccess'));
      } else {
        message.error(t('pages.admin.auditReports.uploadFailed'));
      }
    } else if (file.status === 'error') {
      setUploadedUrl('');
      message.error(file.response?.message || t('pages.admin.auditReports.uploadFailed'));
    } else if (file.status === 'removed') {
      if (uploadedUrl) deleteUploadedFile(uploadedUrl);
      setUploadedUrl('');
    }
  };

  const handleSubmit = async (values: any) => {
    try {
      if (urlMode === 'upload') {
        if (!uploadedUrl) {
          const uploading = fileList.some((f) => f.status === 'uploading');
          message.error(uploading
            ? t('pages.admin.auditReports.waitForUpload')
            : t('pages.admin.auditReports.pleaseUploadFile')
          );
          return false;
        }
        values.audit_report_url = uploadedUrl;
      }

      const { ai_asset_type, ai_maturity_date, ai_custody_value_usd, ai_verification_status, ...rest } = values;
      // 将结构化字段序列化回 additional_info JSON
      const additionalInfo: Record<string, any> = {};
      if (ai_asset_type) additionalInfo.asset_type = ai_asset_type;
      if (ai_maturity_date) {
        additionalInfo.maturity_date = typeof ai_maturity_date === 'string'
          ? ai_maturity_date
          : ai_maturity_date?.format?.('YYYY-MM-DD') ?? String(ai_maturity_date);
      }
      if (ai_custody_value_usd !== undefined && ai_custody_value_usd !== null && ai_custody_value_usd !== '') {
        additionalInfo.custody_value_usd = Number(ai_custody_value_usd);
      }
      if (ai_verification_status) additionalInfo.verification_status = ai_verification_status;
      rest.additional_info = JSON.stringify(additionalInfo);

      if (editRecord?.id) {
        await updateAssetCustody(editRecord.id, rest);
        message.success(t('pages.admin.common.updateSuccess'));
      } else {
        await createAssetCustody(rest);
        message.success(t('pages.admin.common.createSuccess'));
      }
      savedRef.current = true;
      setModalOpen(false);
      actionRef.current?.reload();
      return true;
    } catch (err: any) {
      message.error(getApiErrorMessage(err, t('pages.admin.common.operationFailed')));
      return false;
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await deleteAssetCustody(id);
      message.success(t('pages.admin.common.deleteSuccess'));
      actionRef.current?.reload();
    } catch (err: any) {
      message.error(getApiErrorMessage(err, t('pages.admin.common.deleteFailed')));
    }
  };

  const columns: ProColumns<AdminAPI.AssetCustody>[] = [
    { title: 'ID', dataIndex: 'id', width: 60, search: false },
    { title: t('pages.admin.assetCustody.assetId'), dataIndex: 'asset_id', width: 140,
      renderFormItem: () => (
        <ProFormSelect
          name="asset_id"
          options={assetOptions}
          fieldProps={{ showSearch: true, optionFilterProp: 'label', allowClear: true }}
        />
      ),
      render: (_, record) => assetMap[record.asset_id] ? `${assetMap[record.asset_id]} (${record.asset_id})` : record.asset_id,
    },
    { title: t('pages.admin.assetCustody.custodianName'), dataIndex: 'custodian_name', width: 160 },
    { title: t('pages.admin.assetCustody.custodyType'), dataIndex: 'custody_type', width: 120, search: false },
    { title: t('pages.admin.assetCustody.custodyLocation'), dataIndex: 'custody_location', width: 120, search: false },
    { title: t('pages.admin.assetCustody.custodianAddress'), dataIndex: 'custodian_address', width: 200, search: false,
      ellipsis: true },
    { title: t('pages.admin.assetCustody.auditorName'), dataIndex: 'auditor_name', width: 140, search: false },
    { title: t('pages.admin.assetCustody.lastAuditDate'), dataIndex: 'last_audit_date', width: 120, search: false,
      render: (v: any) => isEpochDate(v) ? '-' : new Date(v).toLocaleDateString() },
    {
      title: t('pages.admin.common.actions'),
      width: 120,
      search: false,
      fixed: 'right',
      render: (_, record) => (
        <Space>
          <a onClick={() => openEdit(record)}>{t('pages.admin.common.edit')}</a>
          <Popconfirm title={t('pages.admin.common.confirmDelete')} onConfirm={() => handleDelete(record.id)}>
            <a style={{ color: 'red' }}>{t('pages.admin.common.delete')}</a>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const initialValues = editRecord ? (() => {
    let extra: Record<string, any> = {};
    try { extra = JSON.parse(editRecord.additional_info || '{}'); } catch {}
    return {
      ...editRecord,
      last_audit_date: isEpochDate(editRecord.last_audit_date) ? undefined : editRecord.last_audit_date,
      ai_asset_type: extra.asset_type ?? '',
      ai_maturity_date: extra.maturity_date || undefined,
      ai_custody_value_usd: extra.custody_value_usd ?? undefined,
      ai_verification_status: extra.verification_status ?? 'Unverified',
    };
  })() : {};

  return (
    <PageContainer>
      <ProTable<AdminAPI.AssetCustody>
        rowKey="id"
        actionRef={actionRef}
        formRef={searchFormRef}
        search={{ onValuesChange: handleValuesChange }}
        columns={columns}
        request={async (params) => {
          const res = await listAssetCustody(params);
          return { data: res.data, success: res.success, total: res.total };
        }}
        toolBarRender={() => [
          <Button key="create" type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            {t('pages.admin.assetCustody.create')}
          </Button>,
        ]}
        scroll={{ x: 1100 }}
        pagination={{ pageSize: 20 }}
      />

      <ModalForm
        title={editRecord ? t('pages.admin.assetCustody.edit') : t('pages.admin.assetCustody.create')}
        open={modalOpen}
        onOpenChange={(open) => {
          setModalOpen(open);
          if (!open) {
            if (!savedRef.current && uploadedUrl) deleteUploadedFile(uploadedUrl);
            resetUpload();
          }
        }}
        onFinish={handleSubmit}
        initialValues={initialValues}
        modalProps={{ destroyOnHidden: true }}
        width={960}
        layout="vertical"
      >
        <ProFormSelect name="asset_id" label={t('pages.admin.assetCustody.assetId')} rules={[{ required: true }]} options={assetOptions} />
        <Row gutter={16}>
          <Col span={12}><ProFormText name="custodian_name" label={t('pages.admin.assetCustody.custodianName')} rules={[{ required: true }]} /></Col>
          <Col span={12}><ProFormText name="custodian_license" label={t('pages.admin.assetCustody.custodianLicense')} /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}><ProFormText name="custody_type" label={t('pages.admin.assetCustody.custodyType')} /></Col>
          <Col span={12}><ProFormText name="custody_location" label={t('pages.admin.assetCustody.custodyLocation')} /></Col>
        </Row>
        <ProFormText name="custodian_address" label={t('pages.admin.assetCustody.custodianAddress')} />
        <Row gutter={16}>
          <Col span={12}><ProFormText name="auditor_name" label={t('pages.admin.assetCustody.auditorName')} /></Col>
          <Col span={12}><ProFormDatePicker name="last_audit_date" label={t('pages.admin.assetCustody.lastAuditDate')} /></Col>
        </Row>
        <Form.Item label={t('pages.admin.assetCustody.auditReportUrl')}>
          <Radio.Group
            value={urlMode}
            onChange={(e) => { setUrlMode(e.target.value); resetUpload(); }}
            style={{ marginBottom: 12 }}
          >
            <Radio.Button value="link"><LinkOutlined /> {t('pages.admin.auditReports.inputUrl')}</Radio.Button>
            <Radio.Button value="upload"><UploadOutlined /> {t('pages.admin.auditReports.uploadFile')}</Radio.Button>
          </Radio.Group>

          {urlMode === 'link' ? (
            <ProFormText name="audit_report_url" noStyle placeholder="https://..." />
          ) : (
            <>
              <Dragger
                name="file"
                action="/api/admin/upload?category=custody"
                headers={{ Authorization: `Bearer ${getAccessToken() || ''}` }}
                accept=".pdf,.png,.jpg,.jpeg,.doc,.docx,.txt,.xls,.xlsx"
                maxCount={1}
                fileList={fileList}
                onChange={handleUploadChange}
                beforeUpload={(file) => {
                  const allowed = [
                    'application/pdf',
                    'image/png',
                    'image/jpeg',
                    'application/msword',
                    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                    'text/plain',
                    'application/vnd.ms-excel',
                    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                  ];
                  if (!allowed.includes(file.type)) {
                    message.error('Only PDF / PNG / JPG / Word / TXT / Excel allowed');
                    return Upload.LIST_IGNORE;
                  }
                  return true;
                }}
              >
                <p className="ant-upload-drag-icon"><InboxOutlined /></p>
                <p className="ant-upload-text">{t('pages.admin.auditReports.dragOrClick')}</p>
                <p className="ant-upload-hint">PDF / PNG / JPG / Word / TXT / Excel，max 20MB</p>
              </Dragger>
              {editRecord?.audit_report_url && fileList.length === 0 && (
                <div style={{ marginTop: 8, fontSize: 12, color: '#888' }}>
                  {t('pages.admin.auditReports.currentFile')}：
                  <a href={editRecord.audit_report_url} target="_blank" rel="noopener noreferrer">
                    {editRecord.audit_report_url}
                  </a>
                </div>
              )}
            </>
          )}
        </Form.Item>
        <Divider orientation="left" style={{ fontSize: 13, color: '#888' }}>
          {t('pages.admin.assetCustody.additionalInfo')}
        </Divider>
        <Row gutter={16}>
          <Col span={12}>
            <ProFormText
              name="ai_asset_type"
              label={t('pages.admin.assetCustody.assetType')}
              placeholder="e.g. US Treasury Bond"
            />
          </Col>
          <Col span={12}>
            <ProFormSelect
              name="ai_verification_status"
              label={t('pages.admin.assetCustody.verificationStatus')}
              options={[
                { label: 'Verified', value: 'Verified' },
                { label: 'Unverified', value: 'Unverified' },
              ]}
            />
          </Col>
        </Row>
        <Row gutter={16}>
          <Col span={8}>
            <ProFormDatePicker
              name="ai_maturity_date"
              label={t('pages.admin.assetCustody.maturityDate')}
              fieldProps={{ style: { width: '100%' } }}
            />
          </Col>
          <Col span={8}>
            <ProFormDigit
              name="ai_custody_value_usd"
              label={t('pages.admin.assetCustody.custodyValueUsd')}
              fieldProps={{ precision: 2, min: 0, formatter: (v) => v ? `$ ${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '' }}
              placeholder="e.g. 1000000"
            />
          </Col>
        </Row>
      </ModalForm>
    </PageContainer>
  );
};

export default AssetCustodyPage;
