import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';

async function getKioskCompanyFilter(): Promise<string> {
  try {
    const result = await postgresClient.query(
      `SELECT setting_key, setting_value FROM kiosk_settings WHERE setting_key IN ('kiosk_company_category_ids', 'kiosk_excluded_company_ids')`
    );
    const map: Record<string, string> = {};
    result.rows.forEach((r: any) => { map[r.setting_key] = r.setting_value || ''; });

    const catIds = (map['kiosk_company_category_ids'] || '1')
      .split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));
    const exclIds = (map['kiosk_excluded_company_ids'] || '')
      .split(',').map((s: string) => parseInt(s.trim(), 10)).filter((n: number) => !isNaN(n));

    const catFilter = catIds.length > 0
      ? `company_id IN (SELECT id FROM companies WHERE company_category_id IN (${catIds.join(',')}))`
      : 'true';
    const exclFilter = exclIds.length > 0
      ? `company_id NOT IN (${exclIds.join(',')})`
      : '';

    return [catFilter, exclFilter].filter(Boolean).join(' AND ');
  } catch (error) {
    console.error('Error fetching kiosk company filter:', error);
    return 'company_id IN (SELECT id FROM companies WHERE company_category_id = 1)';
  }
}

export async function GET(request: NextRequest) {
  try {
    const companyFilter = await getKioskCompanyFilter();
    const excludeCompanyFilter = `AND (${companyFilter})`;

    // Critical tickets (Priority 1-3) - exclude RMM alerts (source = 8), co-managed clients, and excluded classifications
    const criticalTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM tickets 
       WHERE completed_date IS NULL 
         AND is_deleted = false
         AND priority <= 3
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Top 10 critical tickets
    const topCriticalResult = await postgresClient.query(
      `SELECT t.ticket_number, t.title, c.company_name, t.priority
       FROM tickets t
       LEFT JOIN companies c ON t.company_id = c.id
       WHERE t.completed_date IS NULL 
         AND t.is_deleted = false
         AND t.priority <= 3
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}
       ORDER BY t.priority ASC, t.create_date ASC
       LIMIT 10`
    );

    // Tickets waiting engagement (specific statuses) - exclude RMM alerts
    const waitingTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM tickets 
       WHERE completed_date IS NULL 
         AND is_deleted = false
         AND status IN (21, 9, 19)
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Top 10 waiting tickets
    const topWaitingResult = await postgresClient.query(
      `SELECT t.ticket_number, t.title, c.company_name, t.last_activity_date
       FROM tickets t
       LEFT JOIN companies c ON t.company_id = c.id
       WHERE t.completed_date IS NULL 
         AND t.is_deleted = false
         AND t.status IN (21, 9, 19)
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}
       ORDER BY t.last_activity_date ASC NULLS FIRST
       LIMIT 10`
    );

    // Stale tickets (no activity in 7+ days) - exclude RMM alerts
    const staleTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM tickets 
       WHERE completed_date IS NULL 
         AND is_deleted = false
         AND last_activity_date < NOW() - INTERVAL '7 days'
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Top 10 stale tickets (oldest activity first)
    const topStaleResult = await postgresClient.query(
      `SELECT t.ticket_number, t.title, c.company_name, t.last_activity_date
       FROM tickets t
       LEFT JOIN companies c ON t.company_id = c.id
       WHERE t.completed_date IS NULL 
         AND t.is_deleted = false
         AND t.last_activity_date < NOW() - INTERVAL '7 days'
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}
       ORDER BY t.last_activity_date ASC NULLS FIRST
       LIMIT 10`
    );

    // Overdue tickets - exclude RMM alerts
    const overdueTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM tickets 
       WHERE completed_date IS NULL 
         AND is_deleted = false
         AND due_date_time < NOW()
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Top 10 overdue tickets (most overdue first)
    const topOverdueResult = await postgresClient.query(
      `SELECT t.ticket_number, t.title, c.company_name, t.due_date_time
       FROM tickets t
       LEFT JOIN companies c ON t.company_id = c.id
       WHERE t.completed_date IS NULL 
         AND t.is_deleted = false
         AND t.due_date_time < NOW()
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}
       ORDER BY t.due_date_time ASC
       LIMIT 10`
    );

    // Total open tickets - exclude RMM alerts
    const openTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM tickets 
       WHERE completed_date IS NULL
         AND is_deleted = false
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Tickets closed today - exclude RMM alerts
    const closedTodayResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM tickets 
       WHERE DATE(completed_date) = CURRENT_DATE
         AND is_deleted = false
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Top 3 recently closed tickets
    const topClosedResult = await postgresClient.query(
      `SELECT t.ticket_number, t.title, c.company_name, t.completed_date
       FROM tickets t
       LEFT JOIN companies c ON t.company_id = c.id
       WHERE DATE(t.completed_date) = CURRENT_DATE
         AND t.is_deleted = false
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}
       ORDER BY t.completed_date DESC
       LIMIT 3`
    );

    // Average closed tickets per day last week
    const avgClosedLastWeekResult = await postgresClient.query(
      `SELECT ROUND(COUNT(*)::numeric / 7, 1) as avg_per_day
       FROM tickets
       WHERE completed_date >= NOW() - INTERVAL '7 days'
         AND completed_date < NOW()
         AND is_deleted = false
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Average closed tickets per day last month
    const avgClosedLastMonthResult = await postgresClient.query(
      `SELECT ROUND(COUNT(*)::numeric / 30, 1) as avg_per_day
       FROM tickets
       WHERE completed_date >= NOW() - INTERVAL '30 days'
         AND completed_date < NOW()
         AND is_deleted = false
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Average resolution time (last 30 days) - exclude RMM alerts
    const avgResolutionResult = await postgresClient.query(
      `SELECT AVG(EXTRACT(EPOCH FROM (completed_date - create_date))/3600) as avg_hours
       FROM tickets 
       WHERE completed_date >= NOW() - INTERVAL '30 days'
         AND completed_date IS NOT NULL
         AND is_deleted = false
         AND (source IS NULL OR source != 8)
         ${excludeCompanyFilter}`
    );

    // Time entries this week
    const timeEntriesResult = await postgresClient.query(
      `SELECT COALESCE(SUM(hours_worked), 0) as hours
       FROM time_entries 
       WHERE entry_date >= DATE_TRUNC('week', CURRENT_DATE)`
    );

    // Top ticket closers (last 30 days) - using last_activity_resource_id, excluding Autotask system user
    // Only count tickets where the resource has at least 10 minutes (0.167 hours) of time worked
    const topTicketClosersResult = await postgresClient.query(
      `SELECT r.first_name || ' ' || r.last_name as resource_name, 
              COUNT(DISTINCT t.id) as tickets_closed
       FROM tickets t
       INNER JOIN resources r ON t.last_activity_resource_id = r.id
       INNER JOIN (
         SELECT ticket_id, resource_id, SUM(hours_worked) as total_hours
         FROM time_entries
         GROUP BY ticket_id, resource_id
         HAVING SUM(hours_worked) >= 0.167
       ) te ON t.id = te.ticket_id AND r.id = te.resource_id
       WHERE t.completed_date >= NOW() - INTERVAL '30 days'
         AND t.completed_date IS NOT NULL
         AND t.is_deleted = false
         AND (t.source IS NULL OR t.source != 8)
         AND r.id != 4
         ${excludeCompanyFilter}
       GROUP BY r.id, r.first_name, r.last_name
       ORDER BY tickets_closed DESC
       LIMIT 10`
    );

    // Active companies
    const companiesResult = await postgresClient.query(
      `SELECT COUNT(*) as count 
       FROM companies 
       WHERE is_active = true AND company_type = 1`
    );

    // Quotes (if table exists)
    let quotesOpen = 0;
    try {
      const quotesResult = await postgresClient.query(
        `SELECT COUNT(*) as count 
         FROM quotes 
         WHERE status = 'open'`
      );
      quotesOpen = parseInt(quotesResult.rows[0]?.count || '0');
    } catch {
      // Quotes table may not exist
    }

    // NMS Coverage
    let nmsPercentage = 0;
    try {
      const nmsResult = await postgresClient.query(
        `SELECT 
          (SELECT COUNT(*) FROM auvik_tenant_mappings WHERE autotask_company_id IS NOT NULL) as mapped,
          (SELECT COUNT(*) FROM auvik_tenants) as total`
      );
      const mapped = parseInt(nmsResult.rows[0]?.mapped || '0');
      const total = parseInt(nmsResult.rows[0]?.total || '0');
      nmsPercentage = total > 0 ? Math.round((mapped / total) * 100) : 0;
    } catch {
      // Tables may not exist
    }

    // RMM Coverage
    let rmmPercentage = 0;
    try {
      const rmmResult = await postgresClient.query(
        `SELECT 
          (SELECT COUNT(*) FROM rmm_site_mappings WHERE company_id IS NOT NULL) as mapped,
          (SELECT COUNT(*) FROM rmm_sites) as total`
      );
      const mapped = parseInt(rmmResult.rows[0]?.mapped || '0');
      const total = parseInt(rmmResult.rows[0]?.total || '0');
      rmmPercentage = total > 0 ? Math.round((mapped / total) * 100) : 0;
    } catch {
      // Tables may not exist
    }

    // Service Desk - Managed (using primary service desk queues, excluding vendor and alerts)
    const serviceDeskManagedResult = await postgresClient.query(
      `SELECT COUNT(*) as count
       FROM tickets t
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.status NOT IN (21, 9, 19)
         AND t.ticket_type != 4
         AND t.queue_id IN (29682833, 29749490)
         AND (t.ticket_category IS NULL OR t.ticket_category != 171)
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}`
    );

    // Top Issue/Sub-Issue types for Managed Service tickets
    const topManagedIssueTypesResult = await postgresClient.query(
      `SELECT 
         COALESCE(it.label, 'Not Set') as issue_type,
         COALESCE(sit.label, 'Not Set') as sub_issue_type,
         COUNT(*) as count
       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
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.status NOT IN (21, 9, 19)
         AND t.ticket_type != 4
         AND t.queue_id IN (29682833, 29749490)
         AND (t.ticket_category IS NULL OR t.ticket_category != 171)
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}
       GROUP BY it.label, sit.label
       ORDER BY count DESC
       LIMIT 10`
    );

    // Service Desk - T&M (Level 1/2 Support queues)
    const serviceDeskTMResult = await postgresClient.query(
      `SELECT COUNT(*) as count
       FROM tickets t
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.status NOT IN (21, 9, 19)
         AND t.ticket_type != 4
         AND t.queue_id IN (29853766, 29853700)
         AND (t.ticket_category IS NULL OR t.ticket_category != 171)
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}`
    );

    // Vendor Service Desk (All)
    const serviceDeskVendorResult = await postgresClient.query(
      `SELECT COUNT(*) as count
       FROM tickets t
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.ticket_category = 171
         AND (t.source IS NULL OR t.source != 8)
         ${excludeCompanyFilter}`
    );

    // Key Accounts - Hynes Industries
    const hynesTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count
       FROM tickets t
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.company_id = 29861375
         AND (t.source IS NULL OR t.source != 8)`
    );

    // Key Accounts - Seubert and Associates
    const seubertTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count
       FROM tickets t
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.company_id = 29683407
         AND (t.source IS NULL OR t.source != 8)`
    );

    // Key Accounts - Universal Plastics (both locations)
    const universalTicketsResult = await postgresClient.query(
      `SELECT COUNT(*) as count
       FROM tickets t
       WHERE t.completed_date IS NULL
         AND t.is_deleted = false
         AND t.company_id IN (29861395, 29861424)
         AND (t.source IS NULL OR t.source != 8)`
    );

    const stats = {
      criticalTickets: parseInt(criticalTicketsResult.rows[0]?.count || '0'),
      topCritical: topCriticalResult.rows.map((r: any) => ({
        ticketNumber: r.ticket_number,
        title: r.title,
        companyName: r.company_name,
      })),
      waitingTickets: parseInt(waitingTicketsResult.rows[0]?.count || '0'),
      topWaiting: topWaitingResult.rows.map((r: any) => ({
        ticketNumber: r.ticket_number,
        title: r.title,
        companyName: r.company_name,
      })),
      staleTickets: parseInt(staleTicketsResult.rows[0]?.count || '0'),
      topStale: topStaleResult.rows.map((r: any) => ({
        ticketNumber: r.ticket_number,
        title: r.title,
        companyName: r.company_name,
      })),
      overdueTickets: parseInt(overdueTicketsResult.rows[0]?.count || '0'),
      topOverdue: topOverdueResult.rows.map((r: any) => ({
        ticketNumber: r.ticket_number,
        title: r.title,
        companyName: r.company_name,
      })),
      openTickets: parseInt(openTicketsResult.rows[0]?.count || '0'),
      closedToday: parseInt(closedTodayResult.rows[0]?.count || '0'),
      avgClosedLastWeek: parseFloat(avgClosedLastWeekResult.rows[0]?.avg_per_day || '0'),
      avgClosedLastMonth: parseFloat(avgClosedLastMonthResult.rows[0]?.avg_per_day || '0'),
      topClosed: topClosedResult.rows.map((r: any) => ({
        ticketNumber: r.ticket_number,
        title: r.title,
        companyName: r.company_name,
      })),
      avgResolutionHours: parseFloat(avgResolutionResult.rows[0]?.avg_hours || '0'),
      hoursThisWeek: parseFloat(timeEntriesResult.rows[0]?.hours || '0'),
      activeCompanies: parseInt(companiesResult.rows[0]?.count || '0'),
      openQuotes: quotesOpen,
      topTicketClosers: topTicketClosersResult.rows.map((r: any) => ({
        resourceName: r.resource_name,
        ticketsClosed: parseInt(r.tickets_closed),
      })),
      nmsCoverage: nmsPercentage,
      rmmCoverage: rmmPercentage,
      serviceDeskManaged: parseInt(serviceDeskManagedResult.rows[0]?.count || '0'),
      topManagedIssueTypes: topManagedIssueTypesResult.rows.map((r: any) => ({
        issueType: r.issue_type,
        subIssueType: r.sub_issue_type,
        count: parseInt(r.count),
      })),
      serviceDeskTM: parseInt(serviceDeskTMResult.rows[0]?.count || '0'),
      serviceDeskVendor: parseInt(serviceDeskVendorResult.rows[0]?.count || '0'),
      hynesTickets: parseInt(hynesTicketsResult.rows[0]?.count || '0'),
      seubertTickets: parseInt(seubertTicketsResult.rows[0]?.count || '0'),
      universalTickets: parseInt(universalTicketsResult.rows[0]?.count || '0'),
    };

    return NextResponse.json(stats);
  } catch (error) {
    console.error('Error fetching kiosk stats:', error);
    return NextResponse.json(
      { error: 'Failed to fetch kiosk stats' },
      { status: 500 }
    );
  }
}
