import { Injectable, BadRequestException, NotFoundException, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { MktActivity } from '@/entities/mkt-activity.entity';
import { MktInvitation } from '@/entities/mkt-invitation.entity';
import { MktCashback } from '@/entities/mkt-cashback.entity';
import { MktUserInviteStats } from '@/entities/mkt-user-invite-stats.entity';
import { MktInviteWithdrawal } from '@/entities/mkt-invite-withdrawal.entity';
import { Order } from '@/entities/order.entity';
import { User } from '@/entities/user.entity';
import {
  BindInvitationDto,
  CreateInviteWithdrawalDto,
  QueryInviteRecordsDto,
} from './dto/activity.dto';

@Injectable()
export class ActivityService {
  private readonly logger = new Logger(ActivityService.name);

  constructor(
    @InjectRepository(MktActivity)
    private activityRepo: Repository<MktActivity>,
    @InjectRepository(MktInvitation)
    private invitationRepo: Repository<MktInvitation>,
    @InjectRepository(MktCashback)
    private cashbackRepo: Repository<MktCashback>,
    @InjectRepository(MktUserInviteStats)
    private statsRepo: Repository<MktUserInviteStats>,
    @InjectRepository(MktInviteWithdrawal)
    private withdrawalRepo: Repository<MktInviteWithdrawal>,
    @InjectRepository(Order)
    private orderRepo: Repository<Order>,
    @InjectRepository(User)
    private userRepo: Repository<User>,
    private dataSource: DataSource,
  ) {}

  /**
   * 获取启用的邀请返现活动
   */
  async getEnabledInviteCashbackActivity(): Promise<MktActivity | null> {
    return this.activityRepo.findOne({
      where: { type: 'invite_cashback', enabled: true },
    });
  }

  /**
   * 获取用户邀请统计
   */
  async getUserStats(userId: number) {
    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) {
      return {
        inviteCode: '',
        totalInvites: 0,
        totalOrders: 0,
        totalCashback: 0,
        availableBalance: 0,
        withdrawnAmount: 0,
        hasInviter: false,
      };
    }

    let stats = await this.statsRepo.findOne({
      where: { activityId: activity.id, userId },
    });

    if (!stats) {
      // 使用新规则生成6位随机邀请码（0-9A-Z）
      const inviteCode = await this.generateUniqueInviteCode();
      const statsData = {
        activityId: activity.id,
        userId,
        inviteCode,
        totalInvites: 0,
        totalOrders: 0,
        totalCashback: 0,
        availableBalance: 0,
        withdrawnAmount: 0,
      };

      console.log('Creating stats with data:', statsData);

      // 使用 insert 方法直接插入
      const result = await this.statsRepo.insert(statsData);

      // 重新查询获取完整对象
      stats = await this.statsRepo.findOne({
        where: { activityId: activity.id, userId },
      });
    }

    // 检查用户是否已被邀请
    const invitation = await this.invitationRepo.findOne({
      where: { inviteeId: userId },
    });

    return {
      ...stats,
      hasInviter: !!invitation,
    };
  }

  /**
   * 生成唯一的6位邀请码（0-9A-Z）
   */
  private async generateUniqueInviteCode(): Promise<string> {
    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    let code = '';

    // 生成6位随机码
    for (let i = 0; i < 6; i++) {
      code += chars.charAt(Math.floor(Math.random() * chars.length));
    }

    // 检查是否已存在
    const existing = await this.statsRepo.findOne({
      where: { inviteCode: code },
    });

    // 如果重复，递归重新生成
    if (existing) {
      this.logger.warn(`邀请码重复: ${code}，重新生成`);
      return this.generateUniqueInviteCode();
    }

    return code;
  }

  /**
   * 绑定邀请关系
   */
  async bindInvitation(userId: number, dto: BindInvitationDto) {
    // 检查是否已被邀请
    const existing = await this.invitationRepo.findOne({ where: { inviteeId: userId } });
    if (existing) {
      return { success: false, message: '您已有邀请人' };
    }

    // 获取活动
    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) {
      return { success: false, message: '活动未开启' };
    }

    // 通过邀请码查找邀请人统计记录
    const inviterStats = await this.statsRepo.findOne({
      where: { inviteCode: dto.inviteCode },
    });

    if (!inviterStats) {
      return { success: false, message: '邀请码无效' };
    }

    const inviterId = inviterStats.userId;

    // 不能邀请自己
    if (inviterId === userId) {
      return { success: false, message: '不能使用自己的邀请码' };
    }

    // 检查邀请人是否存在
    const inviter = await this.userRepo.findOne({ where: { id: inviterId } });
    if (!inviter) {
      return { success: false, message: '邀请人不存在' };
    }

    // 创建邀请关系
    const invitation = this.invitationRepo.create({
      activityId: activity.id,
      inviterId,
      inviteeId: userId,
      inviteCode: dto.inviteCode,
    });
    await this.invitationRepo.save(invitation);

    // 更新邀请人统计
    inviterStats.totalInvites += 1;
    await this.statsRepo.save(inviterStats);

    return { success: true };
  }

  /**
   * 获取邀请记录列表
   */
  async getInviteRecords(userId: number, dto: QueryInviteRecordsDto) {
    const page = dto.page ?? 1;
    const pageSize = dto.pageSize ?? 20;
    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) return { list: [], total: 0 };

    const [list, total] = await this.invitationRepo.findAndCount({
      where: { activityId: activity.id, inviterId: userId },
      relations: ['invitee'],
      order: { createdAt: 'DESC' },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    // 如果没有邀请记录，直接返回
    if (list.length === 0) {
      return { list: [], total: 0 };
    }

    // 获取每个被邀请人的订单数
    const inviteeIds = list.map((item) => item.inviteeId);
    const orderCounts = await this.orderRepo
      .createQueryBuilder('order')
      .select('order.user_id', 'userId')
      .addSelect('COUNT(*)', 'count')
      .where('order.user_id IN (:...ids)', { ids: inviteeIds })
      .andWhere('order.status = :status', { status: 'completed' })
      .groupBy('order.user_id')
      .getRawMany();

    const orderCountMap = new Map(orderCounts.map((item) => [item.userId, parseInt(item.count)]));

    const records = list.map((item) => ({
      id: item.id,
      inviteeId: item.inviteeId,
      inviteeNickname: item.invitee?.nickname || '用户' + item.inviteeId,
      inviteeAvatar: item.invitee?.avatar || '',
      createdAt: item.createdAt,
      orderCount: orderCountMap.get(item.inviteeId) || 0,
    }));

    return { list: records, total };
  }

  /**
   * 获取返现记录列表
   */
  async getCashbackRecords(userId: number, dto: QueryInviteRecordsDto) {
    const page = dto.page ?? 1;
    const pageSize = dto.pageSize ?? 20;
    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) return { list: [], total: 0 };

    const [list, total] = await this.cashbackRepo.findAndCount({
      where: { activityId: activity.id, inviterId: userId },
      order: { createdAt: 'DESC' },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    return { list, total };
  }

  /**
   * 创建提现申请
   */
  async createWithdrawal(userId: number, dto: CreateInviteWithdrawalDto) {
    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) throw new BadRequestException('活动未开启');

    const stats = await this.statsRepo.findOne({
      where: { activityId: activity.id, userId },
    });
    if (!stats || stats.availableBalance < dto.amount) {
      throw new BadRequestException('余额不足');
    }

    const threshold = activity.config.withdrawThreshold ?? 10;
    if (dto.amount < threshold) {
      throw new BadRequestException(`最低提现金额为${threshold}元`);
    }

    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 创建提现申请
      const withdrawal = queryRunner.manager.create(MktInviteWithdrawal, {
        activity_id: activity.id,
        user_id: userId,
        amount: dto.amount,
        status: 'pending',
      });
      await queryRunner.manager.save(withdrawal);

      // 扣减余额
      stats.availableBalance = Number(stats.availableBalance) - dto.amount;
      await queryRunner.manager.save(stats);

      await queryRunner.commitTransaction();
      return withdrawal;
    } catch (err) {
      await queryRunner.rollbackTransaction();
      throw err;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 获取提现记录列表
   */
  async getWithdrawalRecords(userId: number, dto: QueryInviteRecordsDto) {
    const page = dto.page ?? 1;
    const pageSize = dto.pageSize ?? 20;
    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) return { list: [], total: 0 };

    const [list, total] = await this.withdrawalRepo.findAndCount({
      where: { activity_id: activity.id, user_id: userId },
      order: { created_at: 'DESC' },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    return { list, total };
  }

  /**
   * 订单完成时触发返现（由订单服务调用）
   */
  async handleOrderCompleted(orderId: number) {
    const order = await this.orderRepo.findOne({
      where: { id: orderId },
      relations: ['user'],
    });
    if (!order) return;

    const activity = await this.getEnabledInviteCashbackActivity();
    if (!activity) return;

    // 查找邀请关系
    const invitation = await this.invitationRepo.findOne({
      where: { inviteeId: order.userId },
    });
    if (!invitation) return;

    // 检查是否已有返现记录
    const existing = await this.cashbackRepo.findOne({
      where: { orderId, inviterId: invitation.inviterId },
    });
    if (existing) return;

    // 计算该被邀请人已完成的订单数（不含退款）
    const completedOrders = await this.orderRepo.count({
      where: {
        userId: order.userId,
        status: 'completed',
      },
    });

    const config = activity.config;
    const maxOrderIndex = config.maxOrderIndex ?? 2; // 默认前2单

    // 仅前N单返现
    if (completedOrders > maxOrderIndex) return;

    const orderIndex = completedOrders;

    // 根据订单序号获取返现比例
    let rate: number;
    if (orderIndex === 1) {
      rate = config.firstOrderRate;
    } else if (orderIndex === 2) {
      rate = config.secondOrderRate;
    } else {
      // 第3单及以后使用二单返现比例
      rate = config.secondOrderRate;
    }

    let amount = Number(order.payAmount) * rate;
    amount = Math.max(config.minCashback, Math.min(config.maxCashback, amount));
    amount = Math.round(amount * 100) / 100;

    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 创建返现记录
      const cashback = queryRunner.manager.create(MktCashback, {
        activityId: activity.id,
        inviterId: invitation.inviterId,
        inviteeId: order.userId,
        orderId: order.id,
        orderNo: order.orderNo,
        orderAmount: order.payAmount,
        orderIndex,
        rate,
        amount,
        status: 'settled',
        settledAt: new Date(),
      });
      await queryRunner.manager.save(cashback);

      // 更新邀请人统计
      await queryRunner.manager.increment(
        MktUserInviteStats,
        { activityId: activity.id, userId: invitation.inviterId },
        'totalCashback',
        amount,
      );
      await queryRunner.manager.increment(
        MktUserInviteStats,
        { activityId: activity.id, userId: invitation.inviterId },
        'availableBalance',
        amount,
      );

      // 如果是首单，增加下单人数
      if (orderIndex === 1) {
        await queryRunner.manager.increment(
          MktUserInviteStats,
          { activityId: activity.id, userId: invitation.inviterId },
          'totalOrders',
          1,
        );
      }

      await queryRunner.commitTransaction();
      this.logger.log(
        `订单 ${order.orderNo} 完成，邀请人 ${invitation.inviterId} 获得第${orderIndex}单返现 ${amount} 元（比例${rate * 100}%）`,
      );
    } catch (err: any) {
      await queryRunner.rollbackTransaction();
      this.logger.error(`返现处理失败: ${err?.message}`);
    } finally {
      await queryRunner.release();
    }
  }
}
