'use client';

// 调金币 / 调现金弹窗(受控)。列表页与用户详情页共用,避免两处各写一套。
// 每个弹窗自带「增减 / 设为指定值」两种模式;打开时拉一次 360 概览展示当前余额。
import { useEffect, useState } from 'react';
import { App, Form, Input, InputNumber, Modal, Radio, Segmented } from 'antd';
import { api, errMsg } from '@/lib/api';
import { yuan } from '@/lib/format';
import type { UserOverview } from '@/lib/types';

export type AdjustTargetUser = { id: number; phone: string };

interface ModalProps {
  user: AdjustTargetUser | null;
  open: boolean;
  onClose: () => void;
  onDone?: () => void; // 调整成功后回调(刷新余额/列表)
}

type Balances = { coin: number; cashCents: number; inviteCashCents: number };

const balanceLine = (balances: Balances | null) => (
  <p style={{ color: '#888', marginBottom: 12 }}>
    当前余额:金币 {balances ? balances.coin : '…'} ｜ 现金(金币兑现金){' '}
    {balances ? yuan(balances.cashCents) : '…'} ｜ 邀请奖励金{' '}
    {balances ? yuan(balances.inviteCashCents) : '…'}
  </p>
);

// 弹窗打开时拉一次该用户余额;用户切换/关闭时丢弃过期响应(alive 标记防竞态)。
function useBalances(userId: number | undefined, open: boolean) {
  const [balances, setBalances] = useState<Balances | null>(null);
  useEffect(() => {
    if (!open || userId == null) {
      setBalances(null);
      return;
    }
    let alive = true;
    setBalances(null);
    api
      .get<UserOverview>(`/admin/api/users/${userId}`)
      .then((r) => {
        if (alive)
          setBalances({
            coin: r.data.coin_balance,
            cashCents: r.data.cash_balance_cents,
            inviteCashCents: r.data.invite_cash_balance_cents,
          });
      })
      .catch(() => {});
    return () => {
      alive = false;
    };
  }, [userId, open]);
  return balances;
}

export function AdjustCoinModal({ user, open, onClose, onDone }: ModalProps) {
  const { message } = App.useApp();
  const [form] = Form.useForm();
  const [mode, setMode] = useState<'delta' | 'set'>('delta');
  const balances = useBalances(user?.id, open);

  useEffect(() => {
    if (open) {
      setMode('delta');
      form.resetFields();
    }
  }, [open, form]);

  const submit = async () => {
    if (!user) return;
    const v = await form.validateFields();
    try {
      await api.post(`/admin/api/users/${user.id}/coins`, { mode, ...v });
      message.success(mode === 'set' ? '已设置金币' : '已调整金币');
      onClose();
      onDone?.();
    } catch (e) {
      message.error(errMsg(e));
    }
  };

  return (
    <Modal
      title={`调整金币 - ${user?.phone ?? ''}`}
      open={open}
      onOk={submit}
      onCancel={onClose}
      destroyOnHidden
    >
      {balanceLine(balances)}
      <Form form={form} layout="vertical">
        <Form.Item label="操作方式">
          <Segmented
            value={mode}
            onChange={(v) => setMode(v as 'delta' | 'set')}
            options={[
              { label: '增减', value: 'delta' },
              { label: '设为指定值', value: 'set' },
            ]}
          />
        </Form.Item>
        <Form.Item
          name="amount"
          label={mode === 'set' ? '目标金币值(直接设为该值)' : '金币变动(正=增加,负=扣减)'}
          rules={[
            { required: true },
            ...(mode === 'set' ? [{ type: 'number' as const, min: 0, message: '目标值不能为负' }] : []),
          ]}
        >
          <InputNumber style={{ width: '100%' }} min={mode === 'set' ? 0 : undefined} />
        </Form.Item>
        <Form.Item name="reason" label="原因(入审计)" rules={[{ required: true }]}>
          <Input.TextArea rows={2} />
        </Form.Item>
      </Form>
    </Modal>
  );
}

export function AdjustCashModal({ user, open, onClose, onDone }: ModalProps) {
  const { message } = App.useApp();
  const [form] = Form.useForm();
  // 操作方式改为表单必选项(无默认、手动选);用 watch 驱动金额栏文案/最小值
  const mode = Form.useWatch('mode', form) as 'delta' | 'set' | undefined;
  const balances = useBalances(user?.id, open);

  useEffect(() => {
    if (open) form.resetFields(); // 目标账户 / 操作方式 都重置为「未选」
  }, [open, form]);

  // 输入元,×100 转分后调后端(主要给无现金用户发钱直接测试提现)
  const submit = async () => {
    if (!user) return;
    const v = await form.validateFields(); // 任一必填/必选缺失 → 该项下方红字 + 阻断提交
    const amountCents = Math.round(Number(v.amount_yuan) * 100);
    if (v.mode === 'delta' && amountCents === 0) {
      message.warning('金额不能为 0(且不小于 1 分)');
      return;
    }
    if (v.mode === 'set' && amountCents < 0) {
      message.warning('目标金额不能为负');
      return;
    }
    const acctName = v.account === 'invite_cash' ? '邀请奖励金' : '现金';
    try {
      await api.post(`/admin/api/users/${user.id}/cash`, {
        account: v.account,
        mode: v.mode,
        amount_cents: amountCents,
        reason: v.reason,
      });
      message.success(
        v.mode === 'set'
          ? `已设为 ¥${(amountCents / 100).toFixed(2)} ${acctName}`
          : `已${amountCents > 0 ? '发放' : '扣减'} ¥${(Math.abs(amountCents) / 100).toFixed(2)} ${acctName}`,
      );
      onClose();
      onDone?.();
    } catch (e) {
      message.error(errMsg(e));
    }
  };

  return (
    <Modal
      title={`调现金 - ${user?.phone ?? ''}`}
      open={open}
      onOk={submit}
      onCancel={onClose}
      destroyOnHidden
    >
      {balanceLine(balances)}
      <Form form={form} layout="vertical">
        <Form.Item name="account" label="目标账户" rules={[{ required: true, message: '请选择目标账户' }]}>
          <Radio.Group
            optionType="button"
            buttonStyle="solid"
            options={[
              { label: '金币兑现金账户', value: 'coin_cash' },
              { label: '邀请账户', value: 'invite_cash' },
            ]}
          />
        </Form.Item>
        <Form.Item name="mode" label="操作方式" rules={[{ required: true, message: '请选择操作方式' }]}>
          <Radio.Group
            optionType="button"
            buttonStyle="solid"
            options={[
              { label: '增减', value: 'delta' },
              { label: '设为指定值', value: 'set' },
            ]}
          />
        </Form.Item>
        <Form.Item
          name="amount_yuan"
          label={
            mode === 'set'
              ? '目标现金(元,直接设为该值,须≥0)'
              : '现金变动(元,正=发放,负=扣减;不可扣成负)'
          }
          rules={[
            { required: true, message: '请输入现金变动金额' },
            ...(mode === 'set' ? [{ type: 'number' as const, min: 0, message: '目标值不能为负' }] : []),
          ]}
        >
          <InputNumber
            style={{ width: '100%' }}
            step={0.01}
            precision={2}
            suffix="元"
            min={mode === 'set' ? 0 : undefined}
          />
        </Form.Item>
        <Form.Item name="reason" label="原因(入审计)" rules={[{ required: true, message: '请填写原因' }]}>
          <Input.TextArea rows={2} />
        </Form.Item>
      </Form>
    </Modal>
  );
}
