import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '../infrastructure/persistence/prisma/prisma.service';

/** 基础价常量 */
const BASE_PRICE = 15831; // 正式认种基础价（不变）
const BASE_PORTION_PRICE = 1887; // 预种基础价 [2026-03-01 调整] 9项 floor(18870/10) 取整 + 总部吸收余额
const PORTIONS_PER_TREE = 10; // [2026-03-01 调整] 5 → 10 份/棵

export interface TreePricingConfigResponse {
  basePrice: number;
  basePortionPrice: number;
  currentSupplement: number;
  totalPrice: number;
  totalPortionPrice: number;
  autoIncreaseEnabled: boolean;
  autoIncreaseAmount: number;
  autoIncreaseIntervalDays: number;
  lastAutoIncreaseAt: Date | null;
  nextAutoIncreaseAt: Date | null;
  updatedAt: Date;
}

export interface TreePriceChangeLogItem {
  id: string;
  changeType: string;
  previousSupplement: number;
  newSupplement: number;
  changeAmount: number;
  reason: string | null;
  operatorId: string | null;
  createdAt: Date;
}

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

  constructor(private readonly prisma: PrismaService) {}

  /**
   * 获取当前定价配置，不存在则创建默认配置
   */
  async getConfig(): Promise<TreePricingConfigResponse> {
    let config = await this.prisma.treePricingConfig.findFirst({
      orderBy: { updatedAt: 'desc' },
    });

    if (!config) {
      config = await this.prisma.treePricingConfig.create({
        data: { currentSupplement: 0, autoIncreaseEnabled: false },
      });
      this.logger.log('[TREE-PRICING] Default config created');
    }

    const totalPrice = BASE_PRICE + config.currentSupplement;
    // 预种价格 = 基础预种价(1887) + floor(加价部分/10)
    const totalPortionPrice = BASE_PORTION_PRICE + Math.floor(config.currentSupplement / PORTIONS_PER_TREE);
    return {
      basePrice: BASE_PRICE,
      basePortionPrice: BASE_PORTION_PRICE,
      currentSupplement: config.currentSupplement,
      totalPrice,
      totalPortionPrice,
      autoIncreaseEnabled: config.autoIncreaseEnabled,
      autoIncreaseAmount: config.autoIncreaseAmount,
      autoIncreaseIntervalDays: config.autoIncreaseIntervalDays,
      lastAutoIncreaseAt: config.lastAutoIncreaseAt,
      nextAutoIncreaseAt: config.nextAutoIncreaseAt,
      updatedAt: config.updatedAt,
    };
  }

  /**
   * 手动修改加价金额（事务：同时更新配置 + 写入审计日志）
   * 涨价原因：总部运营成本压力
   */
  async updateSupplement(
    newSupplement: number,
    reason: string,
    operatorId: string,
  ): Promise<TreePricingConfigResponse> {
    // 允许负数（降价对冲），但总价不能低于 0
    if (BASE_PRICE + newSupplement < 0) {
      throw new Error(`调价金额不能低于 -${BASE_PRICE}，否则总价为负`);
    }

    const config = await this.getOrCreateConfig();
    const previousSupplement = config.currentSupplement;
    const changeAmount = newSupplement - previousSupplement;

    if (changeAmount === 0) {
      return this.getConfig();
    }

    await this.prisma.$transaction([
      this.prisma.treePricingConfig.update({
        where: { id: config.id },
        data: {
          currentSupplement: newSupplement,
          updatedBy: operatorId,
        },
      }),
      this.prisma.treePriceChangeLog.create({
        data: {
          changeType: 'MANUAL',
          previousSupplement,
          newSupplement,
          changeAmount,
          reason: reason || '总部运营成本压力调价',
          operatorId,
        },
      }),
    ]);

    this.logger.log(
      `[TREE-PRICING] Manual supplement update: ${previousSupplement} → ${newSupplement} (${changeAmount > 0 ? '+' : ''}${changeAmount}) by ${operatorId}, reason: ${reason}`,
    );

    return this.getConfig();
  }

  /**
   * 更新自动涨价设置
   */
  async updateAutoIncreaseSettings(
    enabled: boolean,
    amount?: number,
    intervalDays?: number,
    operatorId?: string,
  ): Promise<TreePricingConfigResponse> {
    const config = await this.getOrCreateConfig();

    const data: Record<string, unknown> = {
      autoIncreaseEnabled: enabled,
      updatedBy: operatorId || null,
    };

    if (amount !== undefined) {
      if (amount < 0) throw new Error('自动涨价金额不能为负数');
      data.autoIncreaseAmount = amount;
    }

    if (intervalDays !== undefined) {
      if (intervalDays < 1) throw new Error('自动涨价间隔天数不能小于1');
      data.autoIncreaseIntervalDays = intervalDays;
    }

    // 启用时计算下次涨价时间
    if (enabled) {
      const interval = intervalDays ?? config.autoIncreaseIntervalDays;
      if (interval > 0) {
        const nextDate = new Date();
        nextDate.setDate(nextDate.getDate() + interval);
        data.nextAutoIncreaseAt = nextDate;
      }
    } else {
      data.nextAutoIncreaseAt = null;
    }

    await this.prisma.treePricingConfig.update({
      where: { id: config.id },
      data,
    });

    this.logger.log(
      `[TREE-PRICING] Auto-increase settings updated: enabled=${enabled}, amount=${amount ?? config.autoIncreaseAmount}, intervalDays=${intervalDays ?? config.autoIncreaseIntervalDays} by ${operatorId || 'unknown'}`,
    );

    return this.getConfig();
  }

  /**
   * 获取变更审计日志（分页）
   */
  async getChangeLog(
    page: number = 1,
    pageSize: number = 20,
  ): Promise<{ items: TreePriceChangeLogItem[]; total: number }> {
    const [items, total] = await this.prisma.$transaction([
      this.prisma.treePriceChangeLog.findMany({
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.treePriceChangeLog.count(),
    ]);

    return { items, total };
  }

  /**
   * 执行自动涨价（由定时任务调用）
   * 涨价原因：系统自动涨价（总部运营成本压力）
   * @returns true 如果执行了涨价，false 如果未到时间或未启用
   */
  async executeAutoIncrease(): Promise<boolean> {
    const config = await this.prisma.treePricingConfig.findFirst({
      orderBy: { updatedAt: 'desc' },
    });

    if (!config) return false;
    if (!config.autoIncreaseEnabled) return false;
    if (!config.nextAutoIncreaseAt) return false;
    if (config.autoIncreaseAmount <= 0) return false;

    const now = new Date();
    if (now < config.nextAutoIncreaseAt) return false;

    const previousSupplement = config.currentSupplement;
    const newSupplement = previousSupplement + config.autoIncreaseAmount;
    const nextDate = new Date(now);
    nextDate.setDate(nextDate.getDate() + config.autoIncreaseIntervalDays);

    await this.prisma.$transaction([
      this.prisma.treePricingConfig.update({
        where: { id: config.id },
        data: {
          currentSupplement: newSupplement,
          lastAutoIncreaseAt: now,
          nextAutoIncreaseAt: nextDate,
        },
      }),
      this.prisma.treePriceChangeLog.create({
        data: {
          changeType: 'AUTO',
          previousSupplement,
          newSupplement,
          changeAmount: config.autoIncreaseAmount,
          reason: '系统自动涨价（总部运营成本压力）',
          operatorId: 'SYSTEM',
        },
      }),
    ]);

    this.logger.log(
      `[TREE-PRICING] Auto-increase executed: ${previousSupplement} → ${newSupplement} (+${config.autoIncreaseAmount}), next: ${nextDate.toISOString()}`,
    );

    return true;
  }

  /** 获取或创建配置（内部方法） */
  private async getOrCreateConfig() {
    let config = await this.prisma.treePricingConfig.findFirst({
      orderBy: { updatedAt: 'desc' },
    });

    if (!config) {
      config = await this.prisma.treePricingConfig.create({
        data: { currentSupplement: 0, autoIncreaseEnabled: false },
      });
    }

    return config;
  }
}
