import React, { useRef, useState } from 'react';
import { useIntl } from '@umijs/max';
import { PageContainer, ProTable, ModalForm, ProFormText, ProFormDigit, ProFormSwitch, ProFormSelect, ProFormTextArea } from '@ant-design/pro-components';
import type { ProColumns, ActionType, ProFormInstance } from '@ant-design/pro-components';
import { Button, Popconfirm, message, Space, Tag, Row, Col, DatePicker, Divider, Descriptions, Typography, Spin } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import { useReadContract, useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
import { FACTORY_ABI, getContracts } from '@/config/contracts';
import {
  listAssets,
  createAsset,
  updateAsset,
  deleteAsset,
} from '@/services/admin/api';
import { getApiErrorMessage } from '@/utils';

const { Text } = Typography;

// 赎回时间合约面板（仅编辑且有合约地址时显示）
function RedemptionTimePanel({ contractAddress, chainId }: { contractAddress: string; chainId: number }) {
  const [newDate, setNewDate] = useState<dayjs.Dayjs | null>(null);
  const factoryAddress = getContracts(chainId).FACTORY as `0x${string}`;

  const { data: vaultInfo, isLoading, refetch } = useReadContract({
    address: factoryAddress,
    abi: FACTORY_ABI,
    functionName: 'getVaultInfo',
    args: [contractAddress as `0x${string}`],
    chainId: chainId as any,
    query: { enabled: !!contractAddress && !!factoryAddress },
  });

  const nextRedemptionTime = vaultInfo ? parseInt(String((vaultInfo as any[])[8]), 10) : 0;

  const { writeContract, data: txHash, isPending, reset } = useWriteContract();
  const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash: txHash });

  React.useEffect(() => {
    if (isSuccess) {
      message.success('赎回时间已设置');
      reset();
      refetch();
      setNewDate(null);
    }
  }, [isSuccess]);

  if (!isLoading && (!vaultInfo || !nextRedemptionTime)) return null;

  const formatRedemptionTime = (ts: number) => {
    if (!ts) return '--';
    return dayjs.unix(ts).format('YYYY-MM-DD HH:mm:ss');
  };

  const formatTimeUntil = (ts: number) => {
    if (!ts) return '--';
    const diff = ts * 1000 - Date.now();
    if (diff <= 0) return '已到期';
    const days = Math.floor(diff / (1000 * 60 * 60 * 24));
    const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    if (days > 0) return `${days} 天 ${hours} 小时`;
    return `${hours} 小时`;
  };

  const handleSet = () => {
    if (!newDate) return;
    const ts = BigInt(newDate.unix());
    writeContract({
      address: factoryAddress,
      abi: FACTORY_ABI,
      functionName: 'setVaultNextRedemptionTime',
      args: [contractAddress as `0x${string}`, ts],
      chainId: chainId as any,
    });
  };

  return (
    <div style={{ background: '#f9fafb', border: '1px solid #e5e7eb', borderRadius: 8, padding: 16 }}>
      <Text strong style={{ fontSize: 14 }}>赎回时间（合约）</Text>
      {isLoading ? <Spin size="small" style={{ marginLeft: 8 }} /> : (
        <Descriptions size="small" column={2} style={{ marginTop: 8 }}>
          <Descriptions.Item label="当前到期时间">
            <Text code>{formatRedemptionTime(nextRedemptionTime)}</Text>
          </Descriptions.Item>
          <Descriptions.Item label="距到期">
            <Text type={nextRedemptionTime && nextRedemptionTime * 1000 > Date.now() ? 'success' : 'secondary'}>
              {formatTimeUntil(nextRedemptionTime)}
            </Text>
          </Descriptions.Item>
        </Descriptions>
      )}
      <div style={{ display: 'flex', gap: 8, marginTop: 8, alignItems: 'center' }}>
        <DatePicker
          showTime
          value={newDate}
          onChange={setNewDate}
          placeholder="选择新的到期时间"
          style={{ flex: 1 }}
        />
        <Button
          type="primary"
          size="middle"
          loading={isPending || isConfirming}
          disabled={!newDate}
          onClick={handleSet}
        >
          设置到期时间
        </Button>
      </div>
    </div>
  );
}


const AssetsPage: 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.Asset> | null>(null);

  const handleValuesChange = () => {
    clearTimeout(searchTimer.current);
    searchTimer.current = setTimeout(() => searchFormRef.current?.submit(), 500);
  };

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

  const openCreate = () => {
    setEditRecord(null);
    setModalOpen(true);
  };

  const openEdit = (record: AdminAPI.Asset) => {
    setEditRecord(record);
    setModalOpen(true);
  };

  const handleSubmit = async (values: any) => {
    try {
      if (editRecord?.id) {
        await updateAsset(editRecord.id, values);
        message.success(t('pages.admin.common.updateSuccess'));
      } else {
        await createAsset(values);
        message.success(t('pages.admin.common.createSuccess'));
      }
      setModalOpen(false);
      actionRef.current?.reload();
      return true;
    } catch (err: any) {
      const msg =
        err?.response?.data?.message ||
        err?.info?.errorMessage ||
        err?.message ||
        t('pages.admin.common.operationFailed');
      message.error(msg);
      return false;
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await deleteAsset(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.Asset>[] = [
    { title: 'ID', dataIndex: 'id', width: 60, search: false },
    { title: t('pages.admin.assets.assetCode'), dataIndex: 'asset_code', width: 100 },
    { title: t('pages.admin.assets.name'), dataIndex: 'name', width: 140 },
    { title: 'Chain', dataIndex: 'chain_id', width: 80, search: false,
      render: (v: any) => v || '-' },
    { title: 'Contract', dataIndex: 'contract_address', width: 140, search: false,
      render: (v: any) => v ? `${v.slice(0, 6)}...${v.slice(-4)}` : '-' },
    { title: 'Role', dataIndex: 'token_role', width: 100, search: false,
      render: (v: any) => {
        const colorMap: Record<string, string> = { stablecoin: 'blue', yt_token: 'purple', lp_token: 'cyan', product: 'green' };
        return <Tag color={colorMap[v] || 'default'}>{v || 'product'}</Tag>;
      }},
    { title: t('pages.admin.assets.category'), dataIndex: 'category', width: 100,
      valueEnum: { RWA: 'RWA', DeFi: 'DeFi', Staking: 'Staking', Liquidity: 'Liquidity' },
      render: (v: any) => <Tag>{v}</Tag> },
    { title: t('pages.admin.assets.targetApy'), dataIndex: 'target_apy', width: 100, search: false,
      render: (v: any) => `${v}%` },
    { title: t('pages.admin.assets.riskLabel'), dataIndex: 'risk_label', width: 100, search: false },
    { title: t('pages.admin.assets.isFeatured'), dataIndex: 'is_featured', width: 80, search: false,
      render: (v: any) => <Tag color={v ? 'gold' : 'default'}>{v ? t('pages.admin.common.yes') : t('pages.admin.common.no')}</Tag> },
    { title: t('pages.admin.common.isActive'), dataIndex: 'is_active', width: 80, search: false,
      render: (v: any) => <Tag color={v ? 'green' : 'red'}>{v ? t('pages.admin.common.active') : t('pages.admin.common.inactive')}</Tag> },
    { title: t('pages.admin.common.createdAt'), dataIndex: 'created_at', width: 160, search: false,
      render: (v: any) => 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
    ? { ...editRecord }
    : { token_role: 'product', decimals: 18, chain_id: 97, is_active: true, is_featured: false };

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

      <ModalForm
        title={editRecord ? t('pages.admin.assets.edit') : t('pages.admin.assets.create')}
        open={modalOpen}
        onOpenChange={setModalOpen}
        onFinish={handleSubmit}
        initialValues={initialValues}
        modalProps={{ destroyOnHidden: true }}
        width={960}
        layout="vertical"
      >
        <Row gutter={16}>
          <Col span={8}><ProFormText name="asset_code" label={t('pages.admin.assets.assetCode')} rules={[{ required: true }]} tooltip="系统唯一标识符，代码中所有逻辑（合约地址查找、借贷、持有者扫描）均依赖此值。创建后不可修改。" disabled={!!editRecord?.id} /></Col>
          <Col span={8}><ProFormText name="name" label={t('pages.admin.assets.name')} rules={[{ required: true }]} /></Col>
          <Col span={8}>
            <ProFormSelect
              name="token_role"
              label="Token Role"
              rules={[{ required: true }]}
              tooltip="控制资产出现的位置：product=基金市场展示；yt_token=基金市场+借贷抵押品下拉+持有者扫描；stablecoin=借贷稳定币下拉（不出现在基金市场）；lp_token=基金市场展示"
              options={[
                { label: 'Product（基金产品）', value: 'product' },
                { label: 'YT Token（抵押品）', value: 'yt_token' },
                { label: 'Stablecoin（稳定币）', value: 'stablecoin' },
                { label: 'LP Token', value: 'lp_token' },
              ]}
            />
          </Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}><ProFormText name="subtitle" label={t('pages.admin.assets.subtitle')} /></Col>
          <Col span={12}><ProFormText name="token_symbol" label={t('pages.admin.assets.tokenSymbol')} tooltip="链上合约的 symbol()，前端用此值查找合约地址（如 USDC、YT-A）。必须与实际合约一致。" /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}>
            <ProFormSelect
              name="category"
              label={t('pages.admin.assets.category')}
              options={[
                { label: 'RWA', value: 'RWA' },
                { label: 'DeFi', value: 'DeFi' },
                { label: 'Staking', value: 'Staking' },
                { label: 'Liquidity', value: 'Liquidity' },
              ]}
              rules={[{ required: true }]}
            />
          </Col>
          <Col span={12}><ProFormText name="category_color" label={t('pages.admin.assets.categoryColor')} placeholder="#4CAF50" tooltip="十六进制颜色值，用于产品卡片分类标签背景色，格式：#RRGGBB" /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}><ProFormDigit name="decimals" label={t('pages.admin.assets.decimals')} min={0} max={18} fieldProps={{ precision: 0 }} tooltip="代币小数位数，USDC在Arbitrum为6，BSC为18，YT/LP均为18" /></Col>
          <Col span={12}><ProFormText name="icon_url" label={t('pages.admin.assets.iconUrl')} /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={8}>
            <ProFormDigit
              name="chain_id"
              label="Chain ID"
              min={1}
              fieldProps={{ precision: 0 }}
              placeholder="如 97、56、421614、1..."
            />
          </Col>
          <Col span={10}><ProFormText name="contract_address" label="Contract Address" tooltip="链上合约地址（0x...），用于链上数据查询和合约调用，留空则该资产跳过链上读取。" /></Col>
          <Col span={6}><ProFormDigit name="deploy_block" label="Deploy Block" min={0} fieldProps={{ precision: 0 }} tooltip="持有者扫描器（holders scanner）从此区块开始扫描 Transfer 事件。填 0 或留空会跳过扫描，导致持有者数据缺失。" /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}><ProFormText name="underlying_assets" label={t('pages.admin.assets.underlyingAssets')} /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}><ProFormDigit name="target_apy" label={t('pages.admin.assets.targetApy')} min={0} fieldProps={{ step: 0.1 }} /></Col>
          <Col span={12}><ProFormDigit name="pool_cap_usd" label={t('pages.admin.assets.poolCapUsd')} min={0} tooltip="池子上限初始值（USD），后续每小时由快照服务从链上 hardCap 自动覆盖更新。" /></Col>
        </Row>
        <Row gutter={16}>
          <Col span={12}><ProFormDigit name="risk_level" label={t('pages.admin.assets.riskLevel')} min={1} max={5} /></Col>
          <Col span={12}><ProFormText name="risk_label" label={t('pages.admin.assets.riskLabel')} /></Col>
        </Row>
        <ProFormTextArea name="description" label={t('pages.admin.assets.description')} fieldProps={{ rows: 3 }} />
        <Row gutter={16}>
          <Col span={12}><ProFormSwitch name="is_active" label={t('pages.admin.common.isActive')} tooltip="关闭后该资产从所有 API 返回中消失，包括基金市场列表、借贷代币下拉、合约地址接口，链上快照也会停止。" /></Col>
          <Col span={12}><ProFormSwitch name="is_featured" label={t('pages.admin.assets.isFeatured')} /></Col>
        </Row>

        {/* 合约赎回时间（仅编辑 YT Token 且有合约地址时显示）*/}
        {editRecord?.id && editRecord?.contract_address && (
          <>
            <Divider style={{ margin: '16px 0 12px' }} />
            <RedemptionTimePanel
              contractAddress={editRecord.contract_address}
              chainId={editRecord.chain_id ?? 97}
            />
          </>
        )}

      </ModalForm>
    </PageContainer>
  );
};

export default AssetsPage;
