/**
 * Triage Validator
 * Validates classification output against DB picklists.
 * Ensures issueType/subIssueType parent-child relationships are correct,
 * priority exists, queue exists, etc.
 */

import { postgresClient } from './postgres-client';
import {
  ClassificationResult,
  ValidationResult,
  ValidationError,
} from '../types/workflow';

// Cache TTL for picklist data (10 minutes)
const PICKLIST_CACHE_TTL_MS = 10 * 60 * 1000;

interface PicklistCache {
  issueTypes: Set<number>;
  subIssueTypes: Map<number, number>; // value → parent_value
  priorities: Set<number>;
  queues: Set<number>;
  ticketCategories: Set<number>;
  loadedAt: number;
}

export class TriageValidator {
  private cache: PicklistCache | null = null;

  /**
   * Load picklist data from DB into cache.
   */
  private async loadPicklists(forceRefresh = false): Promise<PicklistCache> {
    const now = Date.now();
    if (!forceRefresh && this.cache && now - this.cache.loadedAt < PICKLIST_CACHE_TTL_MS) {
      return this.cache;
    }

    const [issueTypes, subIssueTypes, priorities, queues, ticketCategories] = await Promise.all([
      postgresClient.query(`SELECT value FROM issue_types WHERE is_deleted = false`),
      postgresClient.query(`SELECT value, parent_value FROM sub_issue_types WHERE is_deleted = false`),
      postgresClient.query(`SELECT value FROM priorities WHERE is_active = true`),
      postgresClient.query(`SELECT value FROM queues WHERE is_active = true`),
      postgresClient.query(`SELECT value FROM ticket_categories WHERE is_active = true`),
    ]);

    this.cache = {
      issueTypes: new Set(issueTypes.rows.map((r: any) => Number(r.value))),
      subIssueTypes: new Map(
        subIssueTypes.rows.map((r: any) => [Number(r.value), Number(r.parent_value)])
      ),
      priorities: new Set(priorities.rows.map((r: any) => Number(r.value))),
      queues: new Set(queues.rows.map((r: any) => Number(r.value))),
      ticketCategories: new Set(ticketCategories.rows.map((r: any) => Number(r.value))),
      loadedAt: now,
    };

    console.log(
      `[VALIDATOR] Loaded picklists: ${this.cache.issueTypes.size} issueTypes, ` +
      `${this.cache.subIssueTypes.size} subIssueTypes, ${this.cache.priorities.size} priorities, ` +
      `${this.cache.queues.size} queues, ${this.cache.ticketCategories.size} ticketCategories`
    );

    return this.cache;
  }

  /**
   * Validate a classification result against DB picklists.
   */
  async validate(classification: ClassificationResult): Promise<ValidationResult> {
    const picklists = await this.loadPicklists();
    const errors: ValidationError[] = [];

    // Validate issue type
    if (classification.issue_classification) {
      const issueTypeValue = Number(classification.issue_classification.value);
      if (!picklists.issueTypes.has(issueTypeValue)) {
        errors.push({
          field: 'issue_type',
          message: `Issue type ${issueTypeValue} not found in picklist`,
          value: issueTypeValue,
        });
      }

      // Validate sub-issue type
      if (classification.issue_classification.value_2 != null) {
        const subIssueTypeValue = Number(classification.issue_classification.value_2);
        if (!picklists.subIssueTypes.has(subIssueTypeValue)) {
          errors.push({
            field: 'sub_issue_type',
            message: `Sub-issue type ${subIssueTypeValue} not found in picklist`,
            value: subIssueTypeValue,
          });
        } else {
          // Validate parent-child relationship
          const parentValue = picklists.subIssueTypes.get(subIssueTypeValue);
          if (parentValue !== issueTypeValue) {
            errors.push({
              field: 'sub_issue_type',
              message: `Sub-issue type ${subIssueTypeValue} has parent ${parentValue}, but issue type is ${issueTypeValue}`,
              value: subIssueTypeValue,
            });
          }
        }
      }
    }

    // Validate priority
    if (classification.priority) {
      const priorityValue = Number(classification.priority.value);
      if (!picklists.priorities.has(priorityValue)) {
        errors.push({
          field: 'priority',
          message: `Priority ${priorityValue} not found in picklist`,
          value: priorityValue,
        });
      }
    }

    // Validate queue
    if (classification.queue) {
      const queueValue = Number(classification.queue.value);
      if (!picklists.queues.has(queueValue)) {
        errors.push({
          field: 'queue_id',
          message: `Queue ${queueValue} not found in picklist`,
          value: queueValue,
        });
      }
    }

    if (errors.length > 0) {
      console.warn(`[VALIDATOR] Validation failed with ${errors.length} error(s):`, errors);
    }

    return {
      is_valid: errors.length === 0,
      errors,
    };
  }

  /**
   * Force refresh the picklist cache.
   */
  async refreshCache(): Promise<void> {
    await this.loadPicklists(true);
  }
}

// Export singleton instance
export const triageValidator = new TriageValidator();
