import {
  Injectable,
  NotFoundException,
  BadRequestException,
  Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Merchant } from '@/entities/merchant.entity';
import { MerchantAccount } from '@/entities/merchant-account.entity';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { Review } from '@/entities/review.entity';
import {
  ApplyMerchantDto,
  UpdateMerchantDto,
  QueryMerchantDto,
} from './dto/merchant.dto';

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

  constructor(
    @InjectRepository(Merchant)
    private merchantRepo: Repository<Merchant>,
    @InjectRepository(MerchantAccount)
    private merchantAccountRepo: Repository<MerchantAccount>,
    @InjectRepository(Room)
    private roomRepo: Repository<Room>,
    @InjectRepository(RoomCalendar)
    private roomCalendarRepo: Repository<RoomCalendar>,
    @InjectRepository(Review)
    private reviewRepo: Repository<Review>,
  ) {}

  async apply(sellerId: number, dto: ApplyMerchantDto) {
    const existing = await this.merchantRepo.findOne({ where: { sellerId } });
    if (existing) {
      throw new BadRequestException('您已提交过商家申请');
    }

    const merchant = this.merchantRepo.create({ sellerId, ...dto });
    return this.merchantRepo.save(merchant);
  }

  async findBySellerId(sellerId: number) {
    return this.merchantRepo.findOne({ where: { sellerId } });
  }

  async findById(id: number) {
    const merchant = await this.merchantRepo.findOne({ where: { id } });
    if (!merchant) throw new NotFoundException('商家不存在');

    // 动态计算评价数量（只统计已通过审核的评价）
    const reviewCount = await this.reviewRepo.count({
      where: {
        merchantId: id,
        status: 'visible',
      },
    });

    // 计算平均评分
    const reviewStats = await this.reviewRepo
      .createQueryBuilder('r')
      .select('AVG(r.rating)', 'avgRating')
      .where('r.merchant_id = :merchantId', { merchantId: id })
      .andWhere('r.status = :status', { status: 'visible' })
      .getRawOne();

    const avgRating = reviewStats?.avgRating ? Number(reviewStats.avgRating) : null;
    const rating = (avgRating && !isNaN(avgRating)) ? avgRating : (merchant.rating || 5.0);

    return {
      ...merchant,
      reviewCount,
      rating: Number(rating.toFixed(1)),
    };
  }

  async update(id: number, dto: UpdateMerchantDto) {
    const merchant = await this.findById(id);
    // 审核通过或审核拒绝后修改信息，需要重新进入审核
    if (merchant.status === 'approved' || merchant.status === 'rejected') {
      await this.merchantRepo.update(id, {
        ...dto,
        status: 'pending',
        rejectReason: '',
      });
    } else {
      await this.merchantRepo.update(id, dto);
    }
    return this.findById(id);
  }

  async findPublic(query: QueryMerchantDto) {
    const { page = 1, pageSize = 10, keyword, city, checkInDate } = query;
    const safePage = Number(page) || 1;
    const safePageSize = Number(pageSize) || 10;
    const qb = this.merchantRepo
      .createQueryBuilder('m')
      .where('m.status = :status', { status: 'approved' });

    if (keyword) {
      qb.andWhere('m.shop_name LIKE :kw', { kw: `%${keyword}%` });
    }
    if (city) {
      qb.andWhere('m.city = :city', { city });
    }

    qb.orderBy('m.rating', 'DESC');
    qb.skip((safePage - 1) * safePageSize).take(safePageSize);

    const [list, total] = await qb.getManyAndCount();

    // 使用传入的开始日期，如果没有则使用当天日期
    const targetDate = checkInDate || new Date().toISOString().split('T')[0];

    // 为每个商家获取第一个房源的指定日期房价和评价数量
    const listWithPrice = await Promise.all(
      list.map(async (merchant) => {
        // 获取商家的第一个已审核通过且在售的房源
        const firstRoom = await this.roomRepo.findOne({
          where: {
            merchantId: merchant.id,
            status: 'on_sale',
            auditStatus: 'approved',
          },
          order: { id: 'ASC' },
        });

        let minPrice = 0;
        if (firstRoom) {
          // 获取该房源指定日期的房价
          const calendar = await this.roomCalendarRepo.findOne({
            where: {
              roomId: firstRoom.id,
              date: targetDate,
              status: 'available',
            },
          });

          if (calendar && calendar.price > 0) {
            minPrice = Number(calendar.price);
          } else {
            // 如果没有房量房价记录，使用房源的基础价格
            minPrice = Number(firstRoom.price);
          }
        }

        // 动态计算评价数量（只统计已通过审核的评价）
        const reviewCount = await this.reviewRepo.count({
          where: {
            merchantId: merchant.id,
            status: 'visible',
          },
        });

        // 计算平均评分
        const reviewStats = await this.reviewRepo
          .createQueryBuilder('r')
          .select('AVG(r.rating)', 'avgRating')
          .where('r.merchant_id = :merchantId', { merchantId: merchant.id })
          .andWhere('r.status = :status', { status: 'visible' })
          .getRawOne();

        const avgRating = reviewStats?.avgRating ? Number(reviewStats.avgRating) : null;
        const rating = avgRating !== null ? Number(avgRating.toFixed(1)) : Number(merchant.rating || 5.0);

        return {
          ...merchant,
          minPrice,
          reviewCount,
          rating,
        };
      }),
    );

    return {
      list: listWithPrice,
      total,
      page: safePage,
      pageSize: safePageSize,
      totalPages: Math.ceil(total / safePageSize),
    };
  }

  async findAll(query: QueryMerchantDto) {
    const { page = 1, pageSize = 10, keyword, status, city } = query;
    const qb = this.merchantRepo.createQueryBuilder('m');

    if (keyword) {
      qb.andWhere('(m.shop_name LIKE :kw OR m.phone LIKE :kw)', {
        kw: `%${keyword}%`,
      });
    }
    if (status) {
      qb.andWhere('m.status = :status', { status });
    }
    if (city) {
      qb.andWhere('m.city = :city', { city });
    }

    qb.orderBy('m.createdAt', 'DESC');
    qb.skip((page - 1) * pageSize).take(pageSize);

    const [list, total] = await qb.getManyAndCount();
    return {
      list,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize),
    };
  }

  async approve(id: number) {
    const merchant = await this.findById(id);

    // 更新商家状态为已审核
    await this.merchantRepo.update(id, { status: 'approved' });

    // 自动创建商家账户
    await this.createMerchantAccount(id);

    return { message: '商家已通过审核' };
  }

  async reject(id: number, reason: string) {
    await this.merchantRepo.update(id, {
      status: 'rejected',
      rejectReason: reason,
    });
    return { message: '商家已拒绝' };
  }

  async freeze(id: number) {
    await this.merchantRepo.update(id, { status: 'frozen' });
    return { message: '店铺已冻结' };
  }

  async unfreeze(id: number) {
    await this.merchantRepo.update(id, { status: 'approved' });
    return { message: '店铺已解冻' };
  }

  private async createMerchantAccount(merchantId: number): Promise<void> {
    try {
      const existingAccount = await this.merchantAccountRepo.findOne({
        where: { merchant_id: merchantId },
      });

      if (!existingAccount) {
        const 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);
        this.logger.log(`商家账户创建成功: merchantId=${merchantId}`);
      }
    } catch (error) {
      this.logger.error(`创建商家账户失败: merchantId=${merchantId}`, error);
    }
  }
}
