import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ITenantFinder, TenantContext, TenantStatus, TenantPlan } from '@iconsulting/shared';
import { TenantORM } from '../database/postgres/entities/tenant.orm';

/**
 * 租户查找器实现 (evolution-service)
 * 从数据库直接查询租户信息
 */
@Injectable()
export class TenantFinderService implements ITenantFinder {
  // 内存缓存
  private cache = new Map<string, { tenant: TenantContext; expiresAt: number }>();
  private slugCache = new Map<string, string>(); // slug -> id 映射
  private readonly cacheTtlMs = 5 * 60 * 1000; // 5 分钟

  constructor(
    @InjectRepository(TenantORM)
    private readonly tenantRepo: Repository<TenantORM>,
  ) {}

  async findById(id: string): Promise<TenantContext | null> {
    // 检查缓存
    const cached = this.cache.get(id);
    if (cached && cached.expiresAt > Date.now()) {
      return cached.tenant;
    }

    // 从数据库查询
    const orm = await this.tenantRepo.findOne({ where: { id } });
    if (!orm) {
      return null;
    }

    const tenant = this.toContext(orm);
    this.cache.set(id, { tenant, expiresAt: Date.now() + this.cacheTtlMs });
    this.slugCache.set(orm.slug, orm.id);

    return tenant;
  }

  async findBySlug(slug: string): Promise<TenantContext | null> {
    // 检查 slug 缓存
    const cachedId = this.slugCache.get(slug);
    if (cachedId) {
      return this.findById(cachedId);
    }

    // 从数据库查询
    const orm = await this.tenantRepo.findOne({ where: { slug } });
    if (!orm) {
      return null;
    }

    const tenant = this.toContext(orm);
    this.cache.set(orm.id, { tenant, expiresAt: Date.now() + this.cacheTtlMs });
    this.slugCache.set(slug, orm.id);

    return tenant;
  }

  /**
   * 使缓存失效
   */
  invalidate(tenantId: string): void {
    const cached = this.cache.get(tenantId);
    if (cached) {
      // 清除 slug 缓存
      for (const [slug, id] of this.slugCache.entries()) {
        if (id === tenantId) {
          this.slugCache.delete(slug);
          break;
        }
      }
    }
    this.cache.delete(tenantId);
  }

  /**
   * 清空所有缓存
   */
  clearCache(): void {
    this.cache.clear();
    this.slugCache.clear();
  }

  private toContext(orm: TenantORM): TenantContext {
    return {
      id: orm.id,
      slug: orm.slug,
      name: orm.name,
      status: orm.status as TenantStatus,
      plan: orm.plan as TenantPlan,
      config: orm.config || {},
    };
  }
}
