/**
 * Issue Type Assignment Service
 * Provides utilities to assign parent issue types to sub-issues without direct API endpoints
 */

import postgresClient from '@/lib/services/postgres-client';

export interface IssueTypeAssignment {
  subIssueTypeValue: number;
  parentIssueTypeValue: number;
  parentIssueTypeLabel: string;
}

export interface TicketIssueTypes {
  ticketId: number;
  issueType?: number;
  subIssueType?: number;
  issueTypeLabel?: string;
  subIssueTypeLabel?: string;
  parentIssueTypeLabel?: string;
}

/**
 * Get parent issue type for a given sub-issue type
 */
export async function getParentIssueType(subIssueTypeValue: number): Promise<IssueTypeAssignment | null> {
  try {
    const query = `
      SELECT 
        sit.value as sub_issue_type_value,
        sit.parent_value as parent_issue_type_value,
        it.label as parent_issue_type_label
      FROM sub_issue_types sit
      LEFT JOIN issue_types it ON sit.parent_value = it.value
      WHERE sit.value = $1 AND sit.is_active = true
    `;
    
    const result = await postgresClient.query(query, [subIssueTypeValue]);
    
    if (result.rows.length === 0) {
      return null;
    }
    
    const row = result.rows[0];
    return {
      subIssueTypeValue: row.sub_issue_type_value,
      parentIssueTypeValue: row.parent_issue_type_value,
      parentIssueTypeLabel: row.parent_issue_type_label,
    };
  } catch (error) {
    console.error('Failed to get parent issue type:', error);
    throw error;
  }
}

/**
 * Get all sub-issue types with their parent issue types
 */
export async function getAllSubIssueTypesWithParents(): Promise<IssueTypeAssignment[]> {
  try {
    const query = `
      SELECT 
        sit.value as sub_issue_type_value,
        sit.parent_value as parent_issue_type_value,
        it.label as parent_issue_type_label
      FROM sub_issue_types sit
      LEFT JOIN issue_types it ON sit.parent_value = it.value
      WHERE sit.is_active = true
      ORDER BY sit.parent_value ASC, sit.sort_order ASC
    `;
    
    const result = await postgresClient.query(query);
    
    return result.rows.map(row => ({
      subIssueTypeValue: row.sub_issue_type_value,
      parentIssueTypeValue: row.parent_issue_type_value,
      parentIssueTypeLabel: row.parent_issue_type_label,
    }));
  } catch (error) {
    console.error('Failed to get all sub-issue types with parents:', error);
    throw error;
  }
}

/**
 * Get tickets with their issue types and parent issue type assignments
 */
export async function getTicketsWithIssueTypes(
  limit: number = 100,
  offset: number = 0,
  filters: {
    status?: number;
    priority?: number;
    companyId?: number;
    issueType?: number;
    subIssueType?: number;
  } = {}
): Promise<{ tickets: TicketIssueTypes[], total: number }> {
  try {
    const conditions: string[] = [];
    const params: any[] = [];
    let paramIndex = 1;

    if (filters.status !== undefined) {
      conditions.push(`t.status = $${paramIndex++}`);
      params.push(filters.status);
    }
    if (filters.priority !== undefined) {
      conditions.push(`t.priority = $${paramIndex++}`);
      params.push(filters.priority);
    }
    if (filters.companyId !== undefined) {
      conditions.push(`t.company_id = $${paramIndex++}`);
      params.push(filters.companyId);
    }
    if (filters.issueType !== undefined) {
      conditions.push(`t.issue_type = $${paramIndex++}`);
      params.push(filters.issueType);
    }
    if (filters.subIssueType !== undefined) {
      conditions.push(`t.sub_issue_type = $${paramIndex++}`);
      params.push(filters.subIssueType);
    }

    conditions.push(`t.is_deleted = false`);

    const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';

    const query = `
      SELECT 
        t.id as ticket_id,
        t.issue_type,
        t.sub_issue_type,
        it.label as issue_type_label,
        sit.label as sub_issue_type_label,
        pit.label as parent_issue_type_label
      FROM tickets t
      LEFT JOIN issue_types it ON t.issue_type = it.value
      LEFT JOIN sub_issue_types sit ON t.sub_issue_type = sit.value
      LEFT JOIN issue_types pit ON sit.parent_value = pit.value
      ${whereClause}
      ORDER BY t.create_date DESC
      LIMIT $${paramIndex++}
      OFFSET $${paramIndex++}
    `;

    params.push(limit, offset);

    const result = await postgresClient.query(query, params);
    const tickets = result.rows.map(row => ({
      ticketId: row.ticket_id,
      issueType: row.issue_type,
      subIssueType: row.sub_issue_type,
      issueTypeLabel: row.issue_type_label,
      subIssueTypeLabel: row.sub_issue_type_label,
      parentIssueTypeLabel: row.parent_issue_type_label,
    }));

    // Get total count
    const countQuery = `
      SELECT COUNT(*) as total
      FROM tickets t
      ${whereClause}
    `;

    const countParams = params.slice(0, -2);
    const countResult = await postgresClient.query(countQuery, countParams);
    const total = parseInt(countResult.rows[0].total);

    return { tickets, total };
  } catch (error) {
    console.error('Failed to get tickets with issue types:', error);
    throw error;
  }
}

/**
 * Assign parent issue type to sub-issue types in bulk
 * This can be used to update existing data or create mappings
 */
export async function assignParentIssueTypes(): Promise<number> {
  try {
    // This function demonstrates how you could update records
    // if you needed to assign parent types to existing sub-issues
    // without a direct API endpoint
    
    const query = `
      UPDATE sub_issue_types sit
      SET parent_value = it.value
      FROM issue_types it
      WHERE sit.parent_value IS NULL
        AND sit.label LIKE '%' || it.label || '%'
        AND it.is_active = true
      RETURNING sit.value
    `;
    
    const result = await postgresClient.query(query);
    return result.rows.length;
  } catch (error) {
    console.error('Failed to assign parent issue types:', error);
    throw error;
  }
}

/**
 * Create a lookup function that can be used in other parts of the application
 */
export async function createIssueTypeLookup(): Promise<Map<number, string>> {
  try {
    const assignments = await getAllSubIssueTypesWithParents();
    const lookup = new Map<number, string>();
    
    assignments.forEach(assignment => {
      lookup.set(assignment.subIssueTypeValue, assignment.parentIssueTypeLabel || 'Unknown');
    });
    
    return lookup;
  } catch (error) {
    console.error('Failed to create issue type lookup:', error);
    throw error;
  }
}
