import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { AuditConfigEntity } from '../entity/config';
import { NetaClawAgentEntity } from '../../netaclaw/entity/agent';

const DEFAULT_CACHE_TTL_MS = 30_000;

function normalizeOptionalString(value?: unknown): string {
  if (value === null || value === undefined) {
    return '';
  }
  return String(value).trim();
}

function normalizeOptionalNumber(value?: unknown): number | null {
  if (value === null || value === undefined || value === '') {
    return null;
  }
  const num = Number(value);
  return Number.isFinite(num) ? num : null;
}

function normalizeAgentIds(agentIds: unknown, fallbackAgentId?: unknown): number[] {
  const source = Array.isArray(agentIds)
    ? agentIds
    : typeof agentIds === 'string'
      ? (() => {
          try {
            const parsed = JSON.parse(agentIds);
            return Array.isArray(parsed) ? parsed : agentIds.split(/[;；,，]/);
          } catch {
            return agentIds.split(/[;；,，]/);
          }
        })()
      : [];
  const ids = source
    .map(item => normalizeOptionalNumber(item))
    .filter((item): item is number => item !== null && item > 0);
  const fallback = normalizeOptionalNumber(fallbackAgentId);
  if (ids.length === 0 && fallback !== null && fallback > 0) {
    ids.push(fallback);
  }
  return [...new Set(ids)];
}

/**
 * 审核配置服务
 * 核心功能：根据订单条件匹配最优审核规则，确定使用哪个Agent
 */
@Provide()
@Scope(ScopeEnum.Singleton)
export class AuditConfigService {
  @InjectEntityModel(AuditConfigEntity)
  auditConfigEntity: Repository<AuditConfigEntity>;

  @InjectEntityModel(NetaClawAgentEntity)
  agentInfoEntity: Repository<NetaClawAgentEntity>;

  private static cachedConfigs: AuditConfigEntity[] | null = null;
  private static cacheExpiresAt = 0;
  private static loadingPromise: Promise<AuditConfigEntity[]> | null = null;

  /**
   * 审核路由在订单提交的热路径上，启用规则做短 TTL 缓存。
   * 配置变更会主动清理缓存，TTL 用于兜底兼容直接改库的场景。
   */
  private async getEnabledConfigs(): Promise<AuditConfigEntity[]> {
    const now = Date.now();
    if (
      AuditConfigService.cachedConfigs &&
      AuditConfigService.cacheExpiresAt > now
    ) {
      return AuditConfigService.cachedConfigs;
    }

    if (!AuditConfigService.loadingPromise) {
      AuditConfigService.loadingPromise = this.auditConfigEntity
        .find({
          where: { status: 1 },
          order: { priority: 'DESC', id: 'DESC' },
        })
        .then(configs => {
          AuditConfigService.cachedConfigs = configs;
          const ttl = Number(
            process.env.AUDIT_CONFIG_CACHE_TTL_MS || DEFAULT_CACHE_TTL_MS
          );
          AuditConfigService.cacheExpiresAt =
            Date.now() +
            (Number.isFinite(ttl) && ttl > 0 ? ttl : DEFAULT_CACHE_TTL_MS);
          return configs;
        })
        .finally(() => {
          AuditConfigService.loadingPromise = null;
        });
    }

    return AuditConfigService.loadingPromise;
  }

  /**
   * 清理审核配置缓存。后台规则新增、更新、删除后调用。
   */
  clearCache() {
    AuditConfigService.cachedConfigs = null;
    AuditConfigService.cacheExpiresAt = 0;
    AuditConfigService.loadingPromise = null;
  }

  /**
   * 匹配审核配置：根据订单条件找到最优的配置规则
   * 匹配逻辑：
   *   1. 读取所有启用的配置，按优先级降序
   *   2. 逐条检查是否匹配（条件为空=匹配所有）
   *   3. 返回第一条命中的配置
   */
  async matchConfig(
    orderType: string,
    oemId?: number | string,
    productName?: string,
    carType?: number | string,
    carPower?: number | string,
    productNo?: number | string
  ): Promise<AuditConfigEntity | null> {
    const normalizedOrderType =
      normalizeOptionalString(orderType).toLowerCase();
    const normalizedOemId = normalizeOptionalNumber(oemId);
    const normalizedProductName = normalizeOptionalString(productName);
    const normalizedCarType = normalizeOptionalString(carType);
    const normalizedCarPower = normalizeOptionalString(carPower);
    const normalizedProductNo = normalizeOptionalString(productNo);
    const configs = await this.getEnabledConfigs();

    for (const config of configs) {
      // 检查订单类型
      const configOrderType = normalizeOptionalString(
        config.orderType
      ).toLowerCase();
      if (configOrderType && configOrderType !== normalizedOrderType) {
        continue;
      }
      // 检查主机厂
      const configOemId = normalizeOptionalNumber(config.oemId);
      if (configOemId !== null && configOemId !== normalizedOemId) {
        continue;
      }
      // 检查车辆类型
      const configCarType = normalizeOptionalString(config.carType);
      if (configCarType && configCarType !== normalizedCarType) {
        continue;
      }
      // 检查动力类型（长安燃油/新能源）
      const configCarPower = normalizeOptionalString(config.carPower);
      if (configCarPower && configCarPower !== normalizedCarPower) {
        continue;
      }
      // 检查产品编号，优先使用精确编号匹配
      const configProductNo = normalizeOptionalString(config.productNo);
      if (configProductNo && configProductNo !== normalizedProductNo) {
        continue;
      }
      // 检查产品名称（模糊匹配，支持分号分隔多个关键词，任一命中即匹配）
      const configProductKeyword = normalizeOptionalString(
        config.productKeyword || config.productName
      );
      if (configProductKeyword && normalizedProductName) {
        const keywords = configProductKeyword
          .split(/[;；,，]/)
          .map(k => k.trim())
          .filter(k => k);
        const matched = keywords.some(kw => normalizedProductName.includes(kw));
        if (!matched) {
          continue;
        }
      } else if (configProductKeyword && !normalizedProductName) {
        continue;
      }
      // 全部条件通过，命中此规则
      return config;
    }

    return null;
  }

  /**
   * 根据订单条件获取应使用的Agent ID
   */
  async getAgentIdForOrder(
    orderType: string,
    oemId?: number | string,
    productName?: string,
    carType?: number | string,
    carPower?: number | string,
    productNo?: number | string
  ): Promise<number | null> {
    const ids = await this.getAgentIdsForOrder(
      orderType,
      oemId,
      productName,
      carType,
      carPower,
      productNo
    );
    return ids[0] ?? null;
  }

  /**
   * 根据订单条件获取应使用的Agent ID列表
   */
  async getAgentIdsForOrder(
    orderType: string,
    oemId?: number | string,
    productName?: string,
    carType?: number | string,
    carPower?: number | string,
    productNo?: number | string
  ): Promise<number[]> {
    const config = await this.matchConfig(
      orderType,
      oemId,
      productName,
      carType,
      carPower,
      productNo
    );
    return config ? normalizeAgentIds(config.agentIds, config.agentId) : [];
  }

  /**
   * 获取所有可用的Agent列表（状态=已发布）
   */
  async getAvailableAgents(): Promise<
    { id: number; name: string; label: string }[]
  > {
    const agents = await this.agentInfoEntity.find({
      where: { status: 1 },
      select: ['id', 'name', 'label'],
      order: { createTime: 'DESC' },
    });
    return agents;
  }
}
