import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Button,
  Drawer,
  Form,
  Input,
  InputNumber,
  Modal,
  Radio,
  Select,
  Space,
  Switch,
  Table,
  Tag,
} from 'antd';
import { HistoryOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import { message } from '../../ui/app-message';
import { newOperationId } from '../../utils/operation-id';

interface WalletRow {
  studentId: number;
  studentName: string;
  studentNo?: string;
  balance: number;
  outstandingAmount: number;
  roomType?: string;
  roomNumber?: string;
}

const transactionNames: Record<string, string> = {
  recharge: '充值',
  adjustment: '调账',
  bill_payment: '账单扣款',
  bill_refund: '账单冲正',
};

const WalletsPage: React.FC = () => {
  const [rows, setRows] = useState<WalletRow[]>([]);
  const [loading, setLoading] = useState(false);
  const [keyword, setKeyword] = useState('');
  const [debtOnly, setDebtOnly] = useState(false);
  const [roomType, setRoomType] = useState<string | undefined>();
  const [roomTypes, setRoomTypes] = useState<string[]>([]);
  const [selected, setSelected] = useState<WalletRow | null>(null);
  const [transactions, setTransactions] = useState<any[]>([]);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [form] = Form.useForm();
  const [batchForm] = Form.useForm();
  const [saving, setSaving] = useState(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [batchModalOpen, setBatchModalOpen] = useState(false);

  const fetchRows = useCallback(async () => {
    setLoading(true);
    try {
      const data = await api.get('/wallets', {
        params: { keyword: keyword || undefined, debtOnly, roomType },
      });
      setRows(data as WalletRow[]);
    } catch (error: any) {
      message.error(error?.message || '加载学生余额失败');
    } finally {
      setLoading(false);
    }
  }, [keyword, debtOnly, roomType]);

  useEffect(() => {
    void fetchRows();
  }, [fetchRows]);

  useEffect(() => {
    const fetchRoomTypes = async () => {
      try {
        setRoomTypes((await api.get('/wallets/room-types')) as string[]);
      } catch (error: any) {
        message.error(error?.message || '加载房型失败');
      }
    };
    void fetchRoomTypes();
  }, []);

  useEffect(() => {
    setSelectedRowKeys([]);
  }, [keyword, debtOnly, roomType]);

  const openChange = (row: WalletRow) => {
    setSelected(row);
    form.setFieldsValue({ type: 'recharge', amount: undefined, description: '' });
  };

  const openBatchChange = () => {
    batchForm.setFieldsValue({ type: 'recharge', amount: undefined, description: '' });
    setBatchModalOpen(true);
  };

  const submitChange = async () => {
    if (!selected) return;
    const values = await form.validateFields();
    setSaving(true);
    try {
      const result: any = await api.post('/wallets/change-balance', {
        operationId: newOperationId(),
        studentId: selected.studentId,
        ...values,
      });
      const paid = (result.payments || []).reduce(
        (sum: number, bill: any) => sum + Number(bill.paidAmount || 0),
        0,
      );
      message.success(paid > 0 ? `余额已更新，并自动补扣历史账单` : '余额已更新');
      setSelected(null);
      await fetchRows();
    } catch (error: any) {
      message.error(error?.message || '余额操作失败');
    } finally {
      setSaving(false);
    }
  };

  const submitBatchChange = async () => {
    const values = await batchForm.validateFields();
    setSaving(true);
    try {
      const result: any = await api.post('/wallets/batch-change-balance', {
        operationId: newOperationId(),
        studentIds: selectedRowKeys,
        ...values,
      });
      const paid = (result.results || []).reduce((sum: number, item: any) => {
        return (
          sum +
          (item.payments || []).reduce(
            (paymentSum: number, bill: any) => paymentSum + Number(bill.paidAmount || 0),
            0,
          )
        );
      }, 0);
      message.success(
        paid > 0
          ? `已批量更新 ${selectedRowKeys.length} 名学生余额，并自动补扣历史账单`
          : `已批量更新 ${selectedRowKeys.length} 名学生余额`,
      );
      setBatchModalOpen(false);
      setSelectedRowKeys([]);
      batchForm.resetFields();
      await fetchRows();
    } catch (error: any) {
      message.error(error?.message || '批量余额操作失败');
    } finally {
      setSaving(false);
    }
  };

  const showTransactions = async (row: WalletRow) => {
    setSelected(row);
    setDrawerOpen(true);
    try {
      setTransactions(
        (await api.get('/wallets/transactions', { params: { studentId: row.studentId } })) as any[],
      );
    } catch (error: any) {
      message.error(error?.message || '加载流水失败');
    }
  };

  const columns = useMemo(
    () => [
      {
        title: '学生',
        render: (_: unknown, row: WalletRow) => (
          <>
            <strong>{row.studentName}</strong>
            <div style={{ color: '#999' }}>{row.studentNo || `#${row.studentId}`}</div>
            <div style={{ color: '#999' }}>
              {row.roomType ? `${row.roomType}${row.roomNumber ? ` · ${row.roomNumber}` : ''}` : '未入住'}
            </div>
          </>
        ),
      },
      {
        title: '可用余额',
        dataIndex: 'balance',
        render: (value: number) => (
          <strong style={{ color: Number(value) > 0 ? '#1677ff' : undefined }}>
            ¥{Number(value).toFixed(2)}
          </strong>
        ),
      },
      {
        title: '未付账单',
        dataIndex: 'outstandingAmount',
        render: (value: number) =>
          Number(value) > 0 ? (
            <Tag color="red">¥{Number(value).toFixed(2)}</Tag>
          ) : (
            <Tag color="green">无欠费</Tag>
          ),
      },
      {
        title: '操作',
        render: (_: unknown, row: WalletRow) => (
          <Space>
            <PermissionButton
              permission="wallet:edit"
              type="primary"
              size="small"
              icon={<PlusOutlined />}
              onClick={() => openChange(row)}
            >
              充值/调账
            </PermissionButton>
            <Button size="small" icon={<HistoryOutlined />} onClick={() => showTransactions(row)}>
              流水
            </Button>
          </Space>
        ),
      },
    ],
    [],
  );

  return (
    <div>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          gap: 12,
          marginBottom: 16,
          flexWrap: 'wrap',
        }}
      >
        <Space wrap>
          <Input.Search
            allowClear
            placeholder="搜索姓名或学号"
            style={{ width: 240 }}
            onSearch={setKeyword}
            onChange={(event) => !event.target.value && setKeyword('')}
          />
          <Select
            allowClear
            placeholder="按房型筛选"
            style={{ width: 180 }}
            value={roomType}
            onChange={setRoomType}
            options={roomTypes.map((type) => ({ label: type, value: type }))}
          />
          <span>仅看欠费</span>
          <Switch checked={debtOnly} onChange={setDebtOnly} />
        </Space>
        <Space wrap>
          <PermissionButton
            permission="wallet:edit"
            type="primary"
            icon={<PlusOutlined />}
            disabled={selectedRowKeys.length === 0}
            onClick={openBatchChange}
          >
            批量充值/调账
          </PermissionButton>
          <Button icon={<ReloadOutlined />} onClick={fetchRows}>
            刷新
          </Button>
        </Space>
      </div>
      <Table
        rowKey="studentId"
        loading={loading}
        dataSource={rows}
        columns={columns}
        rowSelection={{ selectedRowKeys, onChange: setSelectedRowKeys }}
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50, 100],
          showTotal: (total) => `共 ${total} 人`,
        }}
      />
      <Modal
        title={`${selected?.studentName || ''} - 余额操作`}
        open={!!selected && !drawerOpen}
        onCancel={() => setSelected(null)}
        onOk={submitChange}
        confirmLoading={saving}
        okText="确认"
      >
        <Form form={form} layout="vertical">
          <Form.Item name="type" label="操作类型" rules={[{ required: true }]}>
            <Radio.Group
              options={[
                { label: '充值', value: 'recharge' },
                { label: '调账', value: 'adjustment' },
              ]}
            />
          </Form.Item>
          <Form.Item
            name="amount"
            label="变动金额"
            extra="充值填正数；调减余额时填写负数。充值后会按最早账单优先自动补扣。"
            rules={[{ required: true, message: '请输入金额' }]}
          >
            <InputNumber precision={2} style={{ width: '100%' }} addonBefore="¥" />
          </Form.Item>
          <Form.Item name="description" label="备注">
            <Input.TextArea maxLength={300} />
          </Form.Item>
        </Form>
      </Modal>
      <Modal
        title={`批量余额操作（${selectedRowKeys.length} 人）`}
        open={batchModalOpen}
        onCancel={() => setBatchModalOpen(false)}
        onOk={submitBatchChange}
        confirmLoading={saving}
        okText="确认批量修改"
      >
        <Form form={batchForm} layout="vertical">
          <div style={{ marginBottom: 16, padding: 12, background: '#f5f5f5', borderRadius: 8 }}>
            已选择 <strong>{selectedRowKeys.length}</strong>{' '}
            名学生，将按相同金额批量修改水电费余额。可先按房型筛选并勾选对应学生后批量缴费。
          </div>
          <Form.Item name="type" label="操作类型" rules={[{ required: true }]}>
            <Radio.Group
              options={[
                { label: '充值', value: 'recharge' },
                { label: '调账', value: 'adjustment' },
              ]}
            />
          </Form.Item>
          <Form.Item
            name="amount"
            label="变动金额（元/人）"
            extra="充值填正数；调减余额时填写负数。充值后会按最早账单优先自动补扣。"
            rules={[{ required: true, message: '请输入金额' }]}
          >
            <InputNumber precision={2} style={{ width: '100%' }} addonBefore="¥" />
          </Form.Item>
          <Form.Item name="description" label="备注">
            <Input.TextArea maxLength={300} />
          </Form.Item>
        </Form>
      </Modal>
      <Drawer
        title={`${selected?.studentName || ''} - 余额流水`}
        width={680}
        open={drawerOpen}
        onClose={() => {
          setDrawerOpen(false);
          setSelected(null);
        }}
      >
        <Table
          rowKey="id"
          dataSource={transactions}
          pagination={{ pageSize: 10 }}
          columns={[
            {
              title: '时间',
              dataIndex: 'createdAt',
              render: (value: string) => dayjs(value).format('YYYY-MM-DD HH:mm'),
            },
            {
              title: '类型',
              dataIndex: 'type',
              render: (value: string) => transactionNames[value] || value,
            },
            {
              title: '金额',
              dataIndex: 'amount',
              render: (value: number) => (
                <span style={{ color: Number(value) >= 0 ? '#389e0d' : '#cf1322' }}>
                  {Number(value) >= 0 ? '+' : ''}¥{Number(value).toFixed(2)}
                </span>
              ),
            },
            {
              title: '变动后余额',
              dataIndex: 'balanceAfter',
              render: (value: number) => `¥${Number(value).toFixed(2)}`,
            },
            {
              title: '关联账单',
              dataIndex: 'billId',
              render: (value: number) => (value ? `#${value}` : '-'),
            },
            { title: '说明', dataIndex: 'description' },
          ]}
        />
      </Drawer>
    </div>
  );
};

export default WalletsPage;
