import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { PrismaService } from '../../infrastructure/database/prisma.service';
import type { ModelTier } from './gateway/ai-gateway.types';

export interface RouterTarget {
  provider: string;
  model: string;
}

export interface TierConfig {
  tier: ModelTier;
  preferred: RouterTarget;
  fallback: RouterTarget;
  maxRetries: number;
}

const DEFAULT_ROUTES: Record<string, TierConfig> = {
  cheap: {
    tier: 'cheap',
    preferred: { provider: 'deepseek', model: 'deepseek-v4-flash' },
    fallback: { provider: 'deepseek', model: 'deepseek-v4-flash' },
    maxRetries: 2,
  },
  primary: {
    tier: 'primary',
    preferred: { provider: 'deepseek', model: 'deepseek-v4-pro' },
    fallback: { provider: 'deepseek', model: 'deepseek-v4-pro' },
    maxRetries: 3,
  },
  strong: {
    tier: 'strong',
    preferred: { provider: 'deepseek', model: 'deepseek-v4-pro' },
    fallback: { provider: 'deepseek', model: 'deepseek-v4-pro' },
    maxRetries: 3,
  },
};

@Injectable()
export class ModelRouter implements OnModuleInit {
  private readonly logger = new Logger(ModelRouter.name);
  private routes: Record<string, TierConfig> = { ...DEFAULT_ROUTES };

  constructor(private readonly prisma: PrismaService) {}

  async onModuleInit() {
    await this.loadFromDb();
  }

  async loadFromDb(): Promise<void> {
    try {
      const rows = await this.prisma.modelRoute.findMany({ where: { isActive: true } });
      if (rows.length === 0) return; // use defaults

      const dbRoutes: Record<string, TierConfig> = {};
      for (const r of rows) {
        dbRoutes[r.tier] = {
          tier: r.tier as ModelTier,
          preferred: { provider: r.preferredProvider, model: r.preferredModel },
          fallback: { provider: r.fallbackProvider, model: r.fallbackModel },
          maxRetries: r.maxRetries,
        };
      }
      this.routes = dbRoutes;
      this.logger.log(`Loaded ${rows.length} model routes from DB`);
    } catch (err: any) {
      this.logger.warn(`Failed to load model routes from DB, using defaults: ${err.message}`);
    }
  }

  resolve(tier: ModelTier, _taskType = '*'): TierConfig {
    return this.routes[tier] || DEFAULT_ROUTES[tier] || DEFAULT_ROUTES.cheap;
  }

  isProviderEnabled(providerName: string): boolean {
    // Providers are checked via ProviderConfig table at call time in AiGatewayService
    return true;
  }

  getRoutes(): TierConfig[] {
    return Object.values(this.routes);
  }
}
