import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource, FindOptionsWhere } from 'typeorm';
import { UserAccount } from '@/entities/user-account.entity';
import { MerchantAccount } from '@/entities/merchant-account.entity';
import { PlatformAccount } from '@/entities/platform-account.entity';
import { UserTransaction } from '@/entities/user-transaction.entity';
import { MerchantTransaction } from '@/entities/merchant-transaction.entity';
import { PlatformTransaction } from '@/entities/platform-transaction.entity';
import { QueryUserAccountsDto, QueryMerchantAccountsDto } from './dto/account.dto';

@Injectable()
export class AccountService {
  constructor(
    @InjectRepository(UserAccount)
    private userAccountRepo: Repository<UserAccount>,
    @InjectRepository(MerchantAccount)
    private merchantAccountRepo: Repository<MerchantAccount>,
    @InjectRepository(PlatformAccount)
    private platformAccountRepo: Repository<PlatformAccount>,
    @InjectRepository(UserTransaction)
    private userTransactionRepo: Repository<UserTransaction>,
    @InjectRepository(MerchantTransaction)
    private merchantTransactionRepo: Repository<MerchantTransaction>,
    @InjectRepository(PlatformTransaction)
    private platformTransactionRepo: Repository<PlatformTransaction>,
    private dataSource: DataSource,
  ) {}

  /**
   * 获取用户账户
   */
  async getUserAccount(userId: number): Promise<UserAccount> {
    let account = await this.userAccountRepo.findOne({ where: { user_id: userId } });

    if (!account) {
      account = this.userAccountRepo.create({
        user_id: userId,
        balance: 0,
        frozen_balance: 0,
        total_income: 0,
        total_expense: 0,
        status: 'active',
      });
      await this.userAccountRepo.save(account);
    }

    return account;
  }

  /**
   * 获取商家账户
   */
  async getMerchantAccount(merchantId: number): Promise<MerchantAccount> {
    let account = await this.merchantAccountRepo.findOne({ where: { merchant_id: merchantId } });

    if (!account) {
      account = this.merchantAccountRepo.create({
        merchant_id: merchantId,
        balance: 0,
        frozen_balance: 0,
        debt_amount: 0,
        total_income: 0,
        total_expense: 0,
        total_settlement: 0,
        total_withdraw: 0,
        pending_settlement: 0,
        status: 'active',
      });
      await this.merchantAccountRepo.save(account);
    }

    return account;
  }

  /**
   * 获取平台账户
   */
  async getPlatformAccount(accountName: string = '主账户'): Promise<PlatformAccount> {
    const account = await this.platformAccountRepo.findOne({ where: { account_name: accountName } });

    if (!account) {
      throw new NotFoundException(
        `平台账户"${accountName}"不存在，请先执行数据库初始化脚本创建平台账户`
      );
    }

    return account;
  }

  /**
   * 用户账户增加余额（邀请返现）
   */
  async addUserBalance(
    userId: number,
    amount: number,
    transactionNo: string,
    businessType: string,
    businessId: number,
    businessNo: string,
    remark: string,
  ): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(UserAccount, {
        where: { user_id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('用户账户不存在');
      }

      if (account.status !== 'active') {
        throw new BadRequestException('账户状态异常');
      }

      const balanceBefore = Number(account.balance);
      const balanceAfter = balanceBefore + amount;

      account.balance = balanceAfter;
      account.total_income = Number(account.total_income) + amount;
      account.version += 1;

      await queryRunner.manager.save(account);

      const transaction = this.userTransactionRepo.create({
        transaction_no: transactionNo,
        user_id: userId,
        account_id: account.id,
        direction: 'income',
        amount,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        transaction_type: '邀请返现',
        business_type: businessType,
        business_id: businessId,
        business_no: businessNo,
        related_account_type: 'platform',
        remark,
      });

      await queryRunner.manager.save(transaction);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 用户账户扣减余额（提现）
   */
  async deductUserBalance(
    userId: number,
    amount: number,
    transactionNo: string,
    businessType: string,
    businessId: number,
    businessNo: string,
    remark: string,
  ): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(UserAccount, {
        where: { user_id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('用户账户不存在');
      }

      if (account.status !== 'active') {
        throw new BadRequestException('账户状态异常');
      }

      const balanceBefore = Number(account.balance);
      if (balanceBefore < amount) {
        throw new BadRequestException('账户余额不足');
      }

      const balanceAfter = balanceBefore - amount;

      account.balance = balanceAfter;
      account.total_expense = Number(account.total_expense) + amount;
      account.version += 1;

      await queryRunner.manager.save(account);

      const transaction = this.userTransactionRepo.create({
        transaction_no: transactionNo,
        user_id: userId,
        account_id: account.id,
        direction: 'expense',
        amount,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        transaction_type: '提现',
        business_type: businessType,
        business_id: businessId,
        business_no: businessNo,
        remark,
      });

      await queryRunner.manager.save(transaction);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 冻结用户余额（提现申请）
   */
  async freezeUserBalance(userId: number, amount: number): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(UserAccount, {
        where: { user_id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('用户账户不存在');
      }

      const balance = Number(account.balance);
      if (balance < amount) {
        throw new BadRequestException('账户余额不足');
      }

      account.balance = balance - amount;
      account.frozen_balance = Number(account.frozen_balance) + amount;
      account.version += 1;

      await queryRunner.manager.save(account);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 解冻用户余额（提现失败/拒绝）
   */
  async unfreezeUserBalance(userId: number, amount: number): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(UserAccount, {
        where: { user_id: userId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('用户账户不存在');
      }

      const frozenBalance = Number(account.frozen_balance);
      if (frozenBalance < amount) {
        throw new BadRequestException('冻结余额不足');
      }

      account.balance = Number(account.balance) + amount;
      account.frozen_balance = frozenBalance - amount;
      account.version += 1;

      await queryRunner.manager.save(account);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 商家账户增加余额（结算）
   */
  async addMerchantBalance(
    merchantId: number,
    amount: number,
    transactionNo: string,
    businessType: string,
    businessId: number,
    businessNo: string,
    remark: string,
  ): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(MerchantAccount, {
        where: { merchant_id: merchantId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('商家账户不存在');
      }

      if (account.status !== 'active') {
        throw new BadRequestException('账户状态异常');
      }

      const balanceBefore = Number(account.balance);
      const balanceAfter = balanceBefore + amount;

      account.balance = balanceAfter;
      account.total_income = Number(account.total_income) + amount;
      account.version += 1;

      await queryRunner.manager.save(account);

      const transaction = this.merchantTransactionRepo.create({
        transaction_no: transactionNo,
        merchant_id: merchantId,
        account_id: account.id,
        direction: 'income',
        amount,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        transaction_type: '订单结算',
        business_type: businessType,
        business_id: businessId,
        business_no: businessNo,
        related_account_type: 'platform',
        remark,
      });

      await queryRunner.manager.save(transaction);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 商家账户扣减余额（提现）
   */
  async deductMerchantBalance(
    merchantId: number,
    amount: number,
    transactionNo: string,
    businessType: string,
    businessId: number,
    businessNo: string,
    remark: string,
  ): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(MerchantAccount, {
        where: { merchant_id: merchantId },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('商家账户不存在');
      }

      if (account.status !== 'active') {
        throw new BadRequestException('账户状态异常');
      }

      const balanceBefore = Number(account.balance);
      if (balanceBefore < amount) {
        throw new BadRequestException('账户余额不足');
      }

      const balanceAfter = balanceBefore - amount;

      account.balance = balanceAfter;
      account.total_expense = Number(account.total_expense) + amount;
      account.version += 1;

      await queryRunner.manager.save(account);

      const transaction = this.merchantTransactionRepo.create({
        transaction_no: transactionNo,
        merchant_id: merchantId,
        account_id: account.id,
        direction: 'expense',
        amount,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        transaction_type: '提现',
        business_type: businessType,
        business_id: businessId,
        business_no: businessNo,
        remark,
      });

      await queryRunner.manager.save(transaction);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 平台账户增加余额（订单收入）
   */
  async addPlatformBalance(
    amount: number,
    serviceFee: number,
    transactionNo: string,
    businessType: string,
    businessId: number,
    businessNo: string,
    remark: string,
  ): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(PlatformAccount, {
        where: { account_name: '主账户' },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('平台账户不存在');
      }

      const balanceBefore = Number(account.balance);
      const amountNum = Number(amount);
      const serviceFeeNum = Number(serviceFee);
      const balanceAfter = parseFloat((balanceBefore + amountNum).toFixed(2));

      account.balance = balanceAfter;
      account.total_income = parseFloat((Number(account.total_income) + amountNum).toFixed(2));
      account.total_service_fee = parseFloat((Number(account.total_service_fee) + serviceFeeNum).toFixed(2));
      account.version += 1;

      await queryRunner.manager.save(account);

      const transaction = this.platformTransactionRepo.create({
        transaction_no: transactionNo,
        account_id: account.id,
        direction: 'income',
        amount,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        transaction_type: '订单收入',
        business_type: businessType,
        business_id: businessId,
        business_no: businessNo,
        remark,
      });

      await queryRunner.manager.save(transaction);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 平台账户扣减余额（结算/返现/提现）
   */
  async deductPlatformBalance(
    amount: number,
    transactionNo: string,
    transactionType: string,
    businessType: string,
    businessId: number,
    businessNo: string,
    remark: string,
  ): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const account = await queryRunner.manager.findOne(PlatformAccount, {
        where: { account_name: '主账户' },
        lock: { mode: 'pessimistic_write' },
      });

      if (!account) {
        throw new NotFoundException('平台账户不存在');
      }

      const balanceBefore = Number(account.balance);
      if (balanceBefore < amount) {
        throw new BadRequestException('平台账户余额不足');
      }

      const balanceAfter = balanceBefore - amount;

      account.balance = balanceAfter;
      account.total_expense = Number(account.total_expense) + amount;

      if (transactionType === '商家结算') {
      } else if (transactionType === '邀请返现') {
      } else if (transactionType === '提现') {
      }

      account.version += 1;

      await queryRunner.manager.save(account);

      const transaction = this.platformTransactionRepo.create({
        transaction_no: transactionNo,
        account_id: account.id,
        direction: 'expense',
        amount,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        transaction_type: transactionType,
        business_type: businessType,
        business_id: businessId,
        business_no: businessNo,
        remark,
      });

      await queryRunner.manager.save(transaction);
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  // ==================== 管理员查询接口 ====================

  /**
   * 查询平台账户列表
   */
  async getPlatformAccounts() {
    const accounts = await this.platformAccountRepo.find({
      order: { created_at: 'DESC' },
    });
    return accounts;
  }

  /**
   * 查询平台账户详情
   */
  async getPlatformAccountDetail(id: number) {
    const account = await this.platformAccountRepo.findOne({ where: { id } });
    if (!account) {
      throw new NotFoundException('平台账户不存在');
    }
    return account;
  }

  /**
   * 查询平台账户余额
   */
  async getPlatformAccountBalance(id: number) {
    const account = await this.platformAccountRepo.findOne({
      where: { id },
      select: ['id', 'account_name', 'balance', 'frozen_balance'],
    });
    if (!account) {
      throw new NotFoundException('平台账户不存在');
    }
    return account;
  }

  /**
   * 查询用户账户列表
   */
  async getUserAccounts(dto: QueryUserAccountsDto) {
    const where: FindOptionsWhere<UserAccount> = {};
    if (dto.status) where.status = dto.status as any;
    if (dto.userId) where.user_id = dto.userId;

    const [list, total] = await this.userAccountRepo.findAndCount({
      where,
      relations: ['user'],
      order: { created_at: 'DESC' },
      skip: ((dto.page ?? 1) - 1) * (dto.pageSize ?? 10),
      take: dto.pageSize ?? 10,
    });

    return { list, total, page: dto.page ?? 1, pageSize: dto.pageSize ?? 10 };
  }

  /**
   * 查询用户账户详情
   */
  async getUserAccountDetail(userId: number) {
    const account = await this.userAccountRepo.findOne({
      where: { user_id: userId },
      relations: ['user'],
    });
    if (!account) {
      throw new NotFoundException('用户账户不存在');
    }
    return account;
  }

  /**
   * 用户账户汇总统计
   */
  async getUserAccountsSummary() {
    const result = await this.userAccountRepo
      .createQueryBuilder('ua')
      .select('COUNT(*)', 'totalAccounts')
      .addSelect('COALESCE(SUM(ua.balance), 0)', 'totalBalance')
      .addSelect('COALESCE(SUM(ua.frozen_balance), 0)', 'totalFrozenBalance')
      .addSelect('COALESCE(SUM(ua.total_income), 0)', 'totalIncome')
      .addSelect('COALESCE(SUM(ua.total_expense), 0)', 'totalExpense')
      .getRawOne();

    return {
      totalAccounts: Number(result?.totalAccounts || 0),
      totalBalance: Number(result?.totalBalance || 0),
      totalFrozenBalance: Number(result?.totalFrozenBalance || 0),
      totalIncome: Number(result?.totalIncome || 0),
      totalExpense: Number(result?.totalExpense || 0),
    };
  }

  /**
   * 查询商家账户列表
   */
  async getMerchantAccounts(dto: QueryMerchantAccountsDto) {
    const where: FindOptionsWhere<MerchantAccount> = {};
    if (dto.status) where.status = dto.status as any;
    if (dto.merchantId) where.merchant_id = dto.merchantId;

    const [list, total] = await this.merchantAccountRepo.findAndCount({
      where,
      relations: ['merchant'],
      order: { created_at: 'DESC' },
      skip: ((dto.page ?? 1) - 1) * (dto.pageSize ?? 10),
      take: dto.pageSize ?? 10,
    });

    return { list, total, page: dto.page ?? 1, pageSize: dto.pageSize ?? 10 };
  }

  /**
   * 查询商家账户详情
   */
  async getMerchantAccountDetail(merchantId: number) {
    const account = await this.merchantAccountRepo.findOne({
      where: { merchant_id: merchantId },
      relations: ['merchant'],
    });
    if (!account) {
      throw new NotFoundException('商家账户不存在');
    }
    return account;
  }

  /**
   * 商家账户汇总统计
   */
  async getMerchantAccountsSummary() {
    const result = await this.merchantAccountRepo
      .createQueryBuilder('ma')
      .select('COUNT(*)', 'totalAccounts')
      .addSelect('COALESCE(SUM(ma.balance), 0)', 'totalBalance')
      .addSelect('COALESCE(SUM(ma.frozen_balance), 0)', 'totalFrozenBalance')
      .addSelect('COALESCE(SUM(ma.debt_amount), 0)', 'totalDebtAmount')
      .addSelect('COALESCE(SUM(ma.total_income), 0)', 'totalIncome')
      .addSelect('COALESCE(SUM(ma.total_expense), 0)', 'totalExpense')
      .addSelect('COALESCE(SUM(ma.pending_settlement), 0)', 'totalPendingSettlement')
      .getRawOne();

    return {
      totalAccounts: Number(result?.totalAccounts || 0),
      totalBalance: Number(result?.totalBalance || 0),
      totalFrozenBalance: Number(result?.totalFrozenBalance || 0),
      totalDebtAmount: Number(result?.totalDebtAmount || 0),
      totalIncome: Number(result?.totalIncome || 0),
      totalExpense: Number(result?.totalExpense || 0),
      totalPendingSettlement: Number(result?.totalPendingSettlement || 0),
    };
  }
}
