import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Between } from 'typeorm';
import { Order } from '@/entities/order.entity';
import { Room } from '@/entities/room.entity';
import { MerchantAccount } from '@/entities/merchant-account.entity';
import dayjs from 'dayjs';

@Injectable()
export class StatisticsService {
  constructor(
    @InjectRepository(Order)
    private orderRepo: Repository<Order>,
    @InjectRepository(Room)
    private roomRepo: Repository<Room>,
    @InjectRepository(MerchantAccount)
    private merchantAccountRepo: Repository<MerchantAccount>,
  ) {}

  /**
   * 获取商家数据概览
   * @param merchantId 商家ID
   */
  async getOverview(merchantId: number) {
    const today = dayjs().format('YYYY-MM-DD');
    const weekStart = dayjs().startOf('week').format('YYYY-MM-DD');
    const monthStart = dayjs().startOf('month').format('YYYY-MM-DD');

    // 今日数据
    const todayData = await this.getStatsByPeriod(
      merchantId,
      `${today} 00:00:00`,
      `${today} 23:59:59`
    );

    // 本周数据
    const weekData = await this.getStatsByPeriod(
      merchantId,
      `${weekStart} 00:00:00`,
      `${today} 23:59:59`
    );

    // 本月数据
    const monthData = await this.getStatsByPeriod(
      merchantId,
      `${monthStart} 00:00:00`,
      `${today} 23:59:59`
    );

    // 在售房源数
    const roomCount = await this.roomRepo.count({
      where: { merchantId, status: 'on_sale' },
    });

    // 账户余额
    const account = await this.merchantAccountRepo.findOne({
      where: { merchant_id: merchantId },
    });

    return {
      today: todayData,
      week: weekData,
      month: monthData,
      roomCount,
      balance: account?.balance || 0,
      availableBalance: account ? Number(account.balance) - Number(account.frozen_balance) : 0,
    };
  }

  /**
   * 获取指定时间段的统计数据
   * @param merchantId 商家ID
   * @param startTime 开始时间
   * @param endTime 结束时间
   */
  private async getStatsByPeriod(
    merchantId: number,
    startTime: string,
    endTime: string
  ) {
    // 订单数量统计
    const orderStats = await this.orderRepo
      .createQueryBuilder('order')
      .select('COUNT(*)', 'totalOrders')
      .addSelect('SUM(CASE WHEN status = "completed" THEN 1 ELSE 0 END)', 'completedOrders')
      .addSelect('SUM(CASE WHEN status = "pending_confirm" THEN 1 ELSE 0 END)', 'pendingOrders')
      .addSelect('SUM(CASE WHEN status = "cancelled" OR status = "refunded" THEN 1 ELSE 0 END)', 'cancelledOrders')
      .where('order.merchantId = :merchantId', { merchantId })
      .andWhere('order.createdAt BETWEEN :startTime AND :endTime', {
        startTime,
        endTime,
      })
      .getRawOne();

    // 收入统计（已完成订单）
    const incomeStats = await this.orderRepo
      .createQueryBuilder('order')
      .select('SUM(order.payAmount)', 'totalIncome')
      .addSelect('SUM(order.payAmount - order.serviceFee)', 'actualIncome')
      .where('order.merchantId = :merchantId', { merchantId })
      .andWhere('order.status = :status', { status: 'completed' })
      .andWhere('order.completedAt BETWEEN :startTime AND :endTime', {
        startTime,
        endTime,
      })
      .getRawOne();

    return {
      orderCount: Number(orderStats?.totalOrders || 0),
      completedOrders: Number(orderStats?.completedOrders || 0),
      pendingOrders: Number(orderStats?.pendingOrders || 0),
      cancelledOrders: Number(orderStats?.cancelledOrders || 0),
      totalIncome: Number(incomeStats?.totalIncome || 0),
      actualIncome: Number(incomeStats?.actualIncome || 0),
    };
  }

  /**
   * 获取收入趋势
   * @param merchantId 商家ID
   * @param type 类型：day（最近7天）、week（最近4周）、month（最近6个月）
   */
  async getIncomeTrend(merchantId: number, type: 'day' | 'week' | 'month' = 'day') {
    const now = dayjs();
    let periods: { label: string; start: string; end: string }[] = [];

    if (type === 'day') {
      // 最近7天
      for (let i = 6; i >= 0; i--) {
        const date = now.subtract(i, 'day');
        periods.push({
          label: date.format('MM-DD'),
          start: date.format('YYYY-MM-DD 00:00:00'),
          end: date.format('YYYY-MM-DD 23:59:59'),
        });
      }
    } else if (type === 'week') {
      // 最近4周
      for (let i = 3; i >= 0; i--) {
        const weekStart = now.subtract(i, 'week').startOf('week');
        const weekEnd = now.subtract(i, 'week').endOf('week');
        periods.push({
          label: `${weekStart.format('MM-DD')}`,
          start: weekStart.format('YYYY-MM-DD 00:00:00'),
          end: weekEnd.format('YYYY-MM-DD 23:59:59'),
        });
      }
    } else if (type === 'month') {
      // 最近6个月
      for (let i = 5; i >= 0; i--) {
        const monthStart = now.subtract(i, 'month').startOf('month');
        const monthEnd = now.subtract(i, 'month').endOf('month');
        periods.push({
          label: monthStart.format('YYYY-MM'),
          start: monthStart.format('YYYY-MM-DD 00:00:00'),
          end: monthEnd.format('YYYY-MM-DD 23:59:59'),
        });
      }
    }

    const trendData = await Promise.all(
      periods.map(async (period) => {
        const stats = await this.orderRepo
          .createQueryBuilder('order')
          .select('COUNT(*)', 'orderCount')
          .addSelect('SUM(order.payAmount)', 'totalIncome')
          .addSelect('SUM(order.payAmount - order.serviceFee)', 'actualIncome')
          .where('order.merchantId = :merchantId', { merchantId })
          .andWhere('order.status = :status', { status: 'completed' })
          .andWhere('order.completedAt BETWEEN :start AND :end', {
            start: period.start,
            end: period.end,
          })
          .getRawOne();

        return {
          label: period.label,
          orderCount: Number(stats?.orderCount || 0),
          totalIncome: Number(stats?.totalIncome || 0),
          actualIncome: Number(stats?.actualIncome || 0),
        };
      })
    );

    return {
      type,
      data: trendData,
    };
  }
}
