import { QueryInterface } from 'sequelize';

/**
 * Migration to create database views for KPI reporting
 * These views pre-aggregate data for faster reporting queries
 */
export async function up(queryInterface: QueryInterface): Promise<void> {
  
  // 1. Request Volume & Status Summary View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_request_volume_summary AS
    SELECT
      w.request_id,
      w.request_number,
      w.title,
      w.status,
      w.priority,
      w.template_type,
      w.submission_date,
      w.closure_date,
      w.created_at,
      u.user_id as initiator_id,
      u.display_name as initiator_name,
      u.department as initiator_department,
      EXTRACT(EPOCH FROM (COALESCE(w.closure_date, NOW()) - w.submission_date)) / 3600 as cycle_time_hours,
      EXTRACT(EPOCH FROM (NOW() - w.submission_date)) / 3600 as age_hours,
      w.current_level,
      w.total_levels,
      w.total_tat_hours,
      CASE
        WHEN w.status IN ('APPROVED', 'REJECTED', 'CLOSED') THEN 'COMPLETED'
        WHEN w.status = 'DRAFT' THEN 'DRAFT'
        ELSE 'IN_PROGRESS'
      END as status_category
    FROM workflow_requests w
    LEFT JOIN users u ON w.initiator_id = u.user_id
    WHERE w.is_deleted = false;
  `);

  // 2. TAT Compliance View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_tat_compliance AS
    SELECT
      al.level_id,
      al.request_id,
      w.request_number,
      w.priority,
      w.status as request_status,
      al.level_number,
      al.approver_id,
      al.approver_name,
      u.department as approver_department,
      al.status as level_status,
      al.tat_hours as allocated_hours,
      al.elapsed_hours,
      al.remaining_hours,
      al.tat_percentage_used,
      al.level_start_time,
      al.level_end_time,
      al.action_date,
      al.tat50_alert_sent,
      al.tat75_alert_sent,
      al.tat_breached,
      CASE
        WHEN al.status IN ('APPROVED', 'REJECTED') AND al.elapsed_hours <= al.tat_hours THEN true
        WHEN al.status IN ('APPROVED', 'REJECTED') AND al.elapsed_hours > al.tat_hours THEN false
        WHEN al.status IN ('PENDING', 'IN_PROGRESS') AND al.tat_percentage_used >= 100 THEN false
        ELSE null
      END as completed_within_tat,
      CASE
        WHEN al.tat_percentage_used < 50 THEN 'ON_TRACK'
        WHEN al.tat_percentage_used < 75 THEN 'AT_RISK'
        WHEN al.tat_percentage_used < 100 THEN 'CRITICAL'
        ELSE 'BREACHED'
      END as tat_status,
      CASE
        WHEN al.status IN ('APPROVED', 'REJECTED') THEN
          al.tat_hours - al.elapsed_hours
        ELSE 0
      END as time_saved_hours
    FROM approval_levels al
    JOIN workflow_requests w ON al.request_id = w.request_id
    LEFT JOIN users u ON al.approver_id = u.user_id
    WHERE w.is_deleted = false;
  `);

  // 3. Approver Performance View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_approver_performance AS
    SELECT
      al.approver_id,
      u.display_name as approver_name,
      u.department,
      u.designation,
      COUNT(*) as total_assignments,
      COUNT(CASE WHEN al.status = 'PENDING' THEN 1 END) as pending_count,
      COUNT(CASE WHEN al.status = 'IN_PROGRESS' THEN 1 END) as in_progress_count,
      COUNT(CASE WHEN al.status = 'APPROVED' THEN 1 END) as approved_count,
      COUNT(CASE WHEN al.status = 'REJECTED' THEN 1 END) as rejected_count,
      AVG(CASE WHEN al.status IN ('APPROVED', 'REJECTED') THEN al.elapsed_hours END) as avg_response_time_hours,
      SUM(CASE WHEN al.elapsed_hours <= al.tat_hours AND al.status IN ('APPROVED', 'REJECTED') THEN 1 ELSE 0 END)::FLOAT / 
        NULLIF(COUNT(CASE WHEN al.status IN ('APPROVED', 'REJECTED') THEN 1 END), 0) * 100 as tat_compliance_percentage,
      COUNT(CASE WHEN al.tat_breached = true THEN 1 END) as breaches_count,
      MIN(CASE WHEN al.status = 'PENDING' OR al.status = 'IN_PROGRESS' THEN 
        EXTRACT(EPOCH FROM (NOW() - al.level_start_time)) / 3600 
      END) as oldest_pending_hours
    FROM approval_levels al
    JOIN users u ON al.approver_id = u.user_id
    JOIN workflow_requests w ON al.request_id = w.request_id
    WHERE w.is_deleted = false
    GROUP BY al.approver_id, u.display_name, u.department, u.designation;
  `);

  // 4. TAT Alerts Summary View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_tat_alerts_summary AS
    SELECT
      ta.alert_id,
      ta.request_id,
      w.request_number,
      w.title as request_title,
      w.priority,
      ta.level_id,
      al.level_number,
      ta.approver_id,
      ta.alert_type,
      ta.threshold_percentage,
      ta.tat_hours_allocated,
      ta.tat_hours_elapsed,
      ta.tat_hours_remaining,
      ta.alert_sent_at,
      ta.expected_completion_time,
      ta.is_breached,
      ta.was_completed_on_time,
      ta.completion_time,
      al.status as level_status,
      EXTRACT(EPOCH FROM (ta.alert_sent_at - ta.level_start_time)) / 3600 as hours_before_alert,
      CASE
        WHEN ta.completion_time IS NOT NULL THEN
          EXTRACT(EPOCH FROM (ta.completion_time - ta.alert_sent_at)) / 3600
        ELSE NULL
      END as response_time_after_alert_hours,
      ta.metadata
    FROM tat_alerts ta
    JOIN workflow_requests w ON ta.request_id = w.request_id
    JOIN approval_levels al ON ta.level_id = al.level_id
    WHERE w.is_deleted = false
    ORDER BY ta.alert_sent_at DESC;
  `);

  // 5. Department-wise Workflow Summary View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_department_summary AS
    SELECT
      u.department,
      COUNT(DISTINCT w.request_id) as total_requests,
      COUNT(DISTINCT CASE WHEN w.status = 'DRAFT' THEN w.request_id END) as draft_requests,
      COUNT(DISTINCT CASE WHEN w.status IN ('PENDING', 'IN_PROGRESS') THEN w.request_id END) as open_requests,
      COUNT(DISTINCT CASE WHEN w.status = 'APPROVED' THEN w.request_id END) as approved_requests,
      COUNT(DISTINCT CASE WHEN w.status = 'REJECTED' THEN w.request_id END) as rejected_requests,
      AVG(CASE WHEN w.closure_date IS NOT NULL THEN 
        EXTRACT(EPOCH FROM (w.closure_date - w.submission_date)) / 3600 
      END) as avg_cycle_time_hours,
      COUNT(DISTINCT CASE WHEN w.priority = 'EXPRESS' THEN w.request_id END) as express_priority_count,
      COUNT(DISTINCT CASE WHEN w.priority = 'STANDARD' THEN w.request_id END) as standard_priority_count
    FROM users u
    LEFT JOIN workflow_requests w ON u.user_id = w.initiator_id AND w.is_deleted = false
    WHERE u.department IS NOT NULL
    GROUP BY u.department;
  `);

  // 6. Daily/Weekly KPI Metrics View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_daily_kpi_metrics AS
    SELECT
      DATE(w.created_at) as date,
      COUNT(*) as requests_created,
      COUNT(CASE WHEN w.submission_date IS NOT NULL AND DATE(w.submission_date) = DATE(w.created_at) THEN 1 END) as requests_submitted,
      COUNT(CASE WHEN w.closure_date IS NOT NULL AND DATE(w.closure_date) = DATE(w.created_at) THEN 1 END) as requests_closed,
      COUNT(CASE WHEN w.status = 'APPROVED' AND DATE(w.closure_date) = DATE(w.created_at) THEN 1 END) as requests_approved,
      COUNT(CASE WHEN w.status = 'REJECTED' AND DATE(w.closure_date) = DATE(w.created_at) THEN 1 END) as requests_rejected,
      AVG(CASE WHEN w.closure_date IS NOT NULL AND DATE(w.closure_date) = DATE(w.created_at) THEN
        EXTRACT(EPOCH FROM (w.closure_date - w.submission_date)) / 3600
      END) as avg_completion_time_hours
    FROM workflow_requests w
    WHERE w.is_deleted = false
    GROUP BY DATE(w.created_at)
    ORDER BY DATE(w.created_at) DESC;
  `);

  // 7. Workflow Aging Report View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_workflow_aging AS
    SELECT
      w.request_id,
      w.request_number,
      w.title,
      w.status,
      w.priority,
      w.current_level,
      w.total_levels,
      w.submission_date,
      EXTRACT(EPOCH FROM (NOW() - w.submission_date)) / (3600 * 24) as age_days,
      CASE
        WHEN EXTRACT(EPOCH FROM (NOW() - w.submission_date)) / (3600 * 24) < 3 THEN 'FRESH'
        WHEN EXTRACT(EPOCH FROM (NOW() - w.submission_date)) / (3600 * 24) < 7 THEN 'NORMAL'
        WHEN EXTRACT(EPOCH FROM (NOW() - w.submission_date)) / (3600 * 24) < 14 THEN 'AGING'
        ELSE 'CRITICAL'
      END as age_category,
      al.approver_name as current_approver,
      al.level_start_time as current_level_start,
      EXTRACT(EPOCH FROM (NOW() - al.level_start_time)) / 3600 as current_level_age_hours,
      al.tat_hours as current_level_tat_hours,
      al.tat_percentage_used as current_level_tat_used
    FROM workflow_requests w
    LEFT JOIN approval_levels al ON w.request_id = al.request_id 
      AND al.level_number = w.current_level
      AND al.status IN ('PENDING', 'IN_PROGRESS')
    WHERE w.status IN ('PENDING', 'IN_PROGRESS')
      AND w.is_deleted = false
    ORDER BY age_days DESC;
  `);

  // 8. Engagement & Quality Metrics View
  await queryInterface.sequelize.query(`
    CREATE OR REPLACE VIEW vw_engagement_metrics AS
    SELECT
      w.request_id,
      w.request_number,
      w.title,
      w.status,
      COUNT(DISTINCT wn.note_id) as work_notes_count,
      COUNT(DISTINCT d.document_id) as documents_count,
      COUNT(DISTINCT p.participant_id) as spectators_count,
      COUNT(DISTINCT al.approver_id) as approvers_count,
      MAX(wn.created_at) as last_comment_date,
      MAX(d.uploaded_at) as last_document_date,
      CASE
        WHEN COUNT(DISTINCT wn.note_id) > 10 THEN 'HIGH'
        WHEN COUNT(DISTINCT wn.note_id) > 5 THEN 'MEDIUM'
        ELSE 'LOW'
      END as engagement_level
    FROM workflow_requests w
    LEFT JOIN work_notes wn ON w.request_id = wn.request_id AND wn.is_deleted = false
    LEFT JOIN documents d ON w.request_id = d.request_id AND d.is_deleted = false
    LEFT JOIN participants p ON w.request_id = p.request_id AND p.participant_type = 'SPECTATOR'
    LEFT JOIN approval_levels al ON w.request_id = al.request_id
    WHERE w.is_deleted = false
    GROUP BY w.request_id, w.request_number, w.title, w.status;
  `);

  // KPI views created
}

export async function down(queryInterface: QueryInterface): Promise<void> {
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_engagement_metrics;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_workflow_aging;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_daily_kpi_metrics;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_department_summary;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_tat_alerts_summary;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_approver_performance;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_tat_compliance;');
  await queryInterface.sequelize.query('DROP VIEW IF EXISTS vw_request_volume_summary;');
  // KPI views dropped
}

