import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { UserBalanceService } from '../user-balance/user-balance.service'
import { Withdraw, WithdrawStatus } from './entities/withdraw.entity'
import { Repository } from 'typeorm'
import BigNumber from 'bignumber.js'
import { BalanceType } from '../user-balance/entities/balance-record.entity'
import { IPaginationOptions, Pagination, paginate } from 'nestjs-typeorm-paginate'
import { PageRequest } from '../common/dto/page-request'
import { withdraw } from '../utils/sand-pay'

@Injectable()
export class WithdrawService {
    constructor(
        private readonly userBalanceService: UserBalanceService,
        @InjectRepository(Withdraw)
        private readonly withdrawRepository: Repository<Withdraw>
    ) {}

    async findAll(req: PageRequest<Withdraw>): Promise<Pagination<Withdraw>> {
        return await paginate<Withdraw>(this.withdrawRepository, req.page, req.search)
    }

    async applyWithdraw(userId: number, amount: string, name: string, account: string, remark?: string) {
        await this.userBalanceService.modifyBalance(
            userId,
            new BigNumber(amount).negated(),
            BalanceType.WITHDRAW,
            remark
        )
        return await this.withdrawRepository.save(
            new Withdraw({
                userId,
                amount: new BigNumber(amount),
                name,
                account,
                status: WithdrawStatus.PENDING,
                remark: remark || '123'
            })
        )
    }

    async rejectWithdraw(id: number) {
        const withdraw = await this.withdrawRepository.findOneBy({ id })
        if (!withdraw) {
            throw new BadRequestException('提现记录不存在')
        }
        if (withdraw.status !== WithdrawStatus.PENDING) {
            throw new BadRequestException('提现记录不可取消')
        }
        await this.userBalanceService.modifyBalance(withdraw.userId, withdraw.amount, BalanceType.RETURN)
        withdraw.status = WithdrawStatus.REJECTED
        return await this.withdrawRepository.save(withdraw)
    }

    async finishWithdraw(id: number) {
        const apply = await this.withdrawRepository.findOneBy({ id })
        if (!apply) {
            throw new BadRequestException('提现记录不存在')
        }
        if (apply.status !== WithdrawStatus.PENDING) {
            throw new BadRequestException('提现记录不可完成')
        }
        try {
            await withdraw(apply.name, apply.account, apply.amount.toNumber())
            apply.status = WithdrawStatus.SUCCESS
            return await this.withdrawRepository.save(apply)
        } catch (error) {
            throw new InternalServerErrorException(error.message)
        }
    }
}
