import { Injectable, Logger } from '@nestjs/common';

const VALID_DEPTH_PREFERENCES = ['light', 'standard', 'deep', 'exam'] as const;
type DepthPreference = (typeof VALID_DEPTH_PREFERENCES)[number];

const TIME_CONSTRAINED_THRESHOLD_MINUTES = 15;
const EXAM_URGENT_DAYS = 14;

interface UserProfileSlice {
  qualityPreference?: string | null;
  dailyAvailableMinutes?: number | null;
  learningGoal?: string | null;
  examTarget?: string | null;
  learningDeadline?: Date | string | null;
}

interface UserSettingsSlice {
  maxDailyAiJobs?: number | null;
  maxDailyTokenBudget?: number | null;
}

export interface PriorityRules {
  version: string;
  depthPreference: DepthPreference;
  learningGoal: string | null;
  hasExamTarget: boolean;
  daysUntilDeadline: number | null;
  isTimeConstrained: boolean;
  dailyAvailableMinutes: number | null;
  isBudgetConstrained: boolean;
  taskSuitability: {
    lightReview: boolean;
    deepAnalysis: boolean;
    quizGeneration: boolean;
    flashcardGeneration: boolean;
    contentSummarization: boolean;
    urgentExamMode: boolean;
  };
}

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

  computePriorityRules(
    profile: UserProfileSlice | null,
    settings: UserSettingsSlice | null,
    targetType: string,
    targetId: string, // reserved: future per-resource priority overrides (API-AI-017 follow-up)
  ): PriorityRules {
    const qualityPreference = this.normalizeDepthPreference(profile?.qualityPreference);
    const dailyAvailableMinutes = profile?.dailyAvailableMinutes ?? null;
    const learningGoal = profile?.learningGoal ?? null;
    const examTarget = profile?.examTarget ?? null;
    const learningDeadline = profile?.learningDeadline ?? null;

    const hasExamTarget = !!examTarget;
    const daysUntilDeadline = learningDeadline
      ? Math.max(0, Math.ceil((new Date(learningDeadline).getTime() - Date.now()) / (24 * 60 * 60 * 1000)))
      : null;
    const isTimeConstrained = dailyAvailableMinutes !== null
      && dailyAvailableMinutes <= TIME_CONSTRAINED_THRESHOLD_MINUTES;

    const maxDailyAiJobs = settings?.maxDailyAiJobs ?? null;
    const maxDailyTokenBudget = settings?.maxDailyTokenBudget ?? null;
    const isBudgetConstrained = (maxDailyAiJobs !== null && maxDailyAiJobs <= 3)
      || (maxDailyTokenBudget !== null && maxDailyTokenBudget <= 10000);

    return {
      version: '1.0',
      depthPreference: qualityPreference,
      learningGoal,
      hasExamTarget,
      daysUntilDeadline,
      isTimeConstrained,
      dailyAvailableMinutes,
      isBudgetConstrained,
      taskSuitability: this.computeTaskSuitability(
        qualityPreference,
        isTimeConstrained,
        isBudgetConstrained,
        hasExamTarget,
        daysUntilDeadline,
        targetType,
      ),
    };
  }

  // ── Depth Preference Normalization ──

  private normalizeDepthPreference(raw: string | null | undefined): DepthPreference {
    if (!raw) return 'standard';
    const lower = raw.toLowerCase();
    if ((VALID_DEPTH_PREFERENCES as readonly string[]).includes(lower)) {
      return lower as DepthPreference;
    }
    this.logger.warn(`Unknown qualityPreference="${raw}", falling back to "standard"`);
    return 'standard';
  }

  // ── Task Suitability ──

  private computeTaskSuitability(
    qualityPreference: DepthPreference,
    isTimeConstrained: boolean,
    isBudgetConstrained: boolean,
    hasExamTarget: boolean,
    daysUntilDeadline: number | null,
    targetType: string,
  ) {
    const isUrgent = hasExamTarget && daysUntilDeadline !== null && daysUntilDeadline <= EXAM_URGENT_DAYS;

    // Scope-based adjustments: knowledge_base scope favors content summarization;
    // material scope favors light review
    const isKnowledgeBaseScope = targetType === 'knowledge_base';

    return {
      lightReview: true,

      deepAnalysis: qualityPreference !== 'light'
        && !isTimeConstrained
        && !isBudgetConstrained,

      quizGeneration: qualityPreference !== 'light' || hasExamTarget,

      flashcardGeneration: qualityPreference !== 'light' || hasExamTarget,

      contentSummarization: (qualityPreference === 'deep' || qualityPreference === 'exam')
        && isKnowledgeBaseScope,

      urgentExamMode: isUrgent,
    };
  }

  /**
   * Compute numeric job priority for poll ordering (lower = higher priority).
   * Must be called after computePriorityRules to get taskSuitability.
   */
  computeJobPriority(
    profile: UserProfileSlice | null,
    settings: UserSettingsSlice | null,
    targetType: string,
  ): number {
    const rules = this.computePriorityRules(profile, settings, targetType, '');
    const { taskSuitability, hasExamTarget, depthPreference, isTimeConstrained } = rules;

    if (taskSuitability.urgentExamMode) return 0;
    if (hasExamTarget) return 10;
    if (depthPreference === 'deep' || depthPreference === 'exam') return 20;

    let priority = 50;
    if (isTimeConstrained && priority > 10) priority -= 5;
    if (targetType === 'knowledge_base' && priority > 5) priority -= 5;

    return priority;
  }
}
