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

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const period = searchParams.get('period') || 'D30';
  const sort = searchParams.get('sort') || 'billable_hours';
  const order = searchParams.get('order') === 'asc' ? 'ASC' : 'DESC';
  const page = Math.max(1, parseInt(searchParams.get('page') || '1'));
  const pageSize = 50;
  const offset = (page - 1) * pageSize;

  const intervalMap: Record<string, string> = {
    D7: '7 days',
    D30: '30 days',
    D90: '90 days',
  };
  const interval = intervalMap[period] || '30 days';

  const allowedSorts: Record<string, string> = {
    hours_worked: 'hours_worked',
    billable_hours: 'billable_hours',
    teams_meetings_attended: 'teams_meetings_attended',
    teams_chat_messages: 'teams_chat_messages',
    emails_sent: 'emails_sent',
    last_activity: 'last_active',
    display_name: 'display_name',
    zoom_call_count: 'zoom_call_count',
    zoom_meeting_count: 'zoom_meeting_count',
  };
  const sortCol = allowedSorts[sort] || 'billable_hours';

  try {
    const latestResult = await postgresClient.query(
      `SELECT MAX(period_end) as latest_date FROM engagement_snapshots WHERE period_type = $1`,
      [period]
    );
    const latestDate = latestResult.rows[0]?.latest_date;

    if (!latestDate) {
      return NextResponse.json({ users: [], pagination: { total: 0, page, pageSize } });
    }

    const countResult = await postgresClient.query(
      `SELECT COUNT(*) as total
       FROM graph_users gu
       JOIN (
         SELECT DISTINCT ON (LOWER(email)) id, email
         FROM resources
         WHERE (is_deleted = false OR is_deleted IS NULL) AND email IS NOT NULL
         ORDER BY LOWER(email), id
       ) r ON LOWER(r.email) = LOWER(gu.email)
       LEFT JOIN engagement_snapshots es_cnt
         ON LOWER(es_cnt.user_email) = LOWER(gu.email)
         AND es_cnt.period_type = $1 AND es_cnt.period_end = $2
       WHERE gu.account_enabled = true
         AND LOWER(gu.email) LIKE '%@wulfconsulting.%'
         AND LOWER(gu.email) NOT LIKE '%#ext#%'
         AND NOT (
           es_cnt.user_email IS NOT NULL
           AND COALESCE(es_cnt.emails_received, 0) = 0
           AND COALESCE(es_cnt.teams_chat_messages, 0) = 0
           AND COALESCE(es_cnt.teams_meetings_attended, 0) = 0
           AND COALESCE(es_cnt.teams_calls, 0) = 0
         )`,
      [period, latestDate]
    );
    const total = parseInt(countResult.rows[0]?.total ?? '0');

    const usersResult = await postgresClient.query(
      `SELECT
         gu.id as graph_user_id,
         gu.display_name,
         gu.email,
         gu.job_title,
         gu.department,
         r.id as autotask_resource_id,
         COALESCE(te_agg.total_hours, 0) as hours_worked,
         COALESCE(te_agg.billable_hours, 0) as billable_hours,
         COALESCE(es.teams_chat_messages, 0) as teams_chat_messages,
         COALESCE(es.teams_private_messages, 0) as teams_private_messages,
         COALESCE(es.teams_calls, 0) as teams_calls,
         COALESCE(es.teams_meetings_attended, 0) as teams_meetings_attended,
         COALESCE(es.teams_meetings_organized, 0) as teams_meetings_organized,
         COALESCE(mc.emails_sent, 0) as emails_sent,
         COALESCE(mc.emails_received, 0) as emails_received,
         COALESCE(es.emails_read, 0) as emails_read,
         COALESCE(es.audio_duration_seconds, 0) as audio_duration_seconds,
         COALESCE(es.meeting_duration_seconds, 0) as meeting_duration_seconds,
         COALESCE(es.meetings_with_external, 0) as meetings_with_external,
         LEAST(GREATEST(es.last_activity_date, last_te.entry_date::date), CURRENT_DATE) as last_active,
         COALESCE(zc.zoom_call_count, 0) as zoom_call_count,
         COALESCE(zc.zoom_client_call_count, 0) as zoom_client_call_count,
         COALESCE(zc.zoom_call_duration_seconds, 0) as zoom_call_duration_seconds,
         COALESCE(zm.zoom_meeting_count, 0) as zoom_meeting_count,
         COALESCE(zm.zoom_client_meeting_count, 0) as zoom_client_meeting_count
       FROM graph_users gu
       LEFT JOIN engagement_snapshots es
         ON LOWER(es.user_email) = LOWER(gu.email)
         AND es.period_type = $1
         AND es.period_end = $2
       JOIN (
         SELECT DISTINCT ON (LOWER(email)) *
         FROM resources
         WHERE (is_deleted = false OR is_deleted IS NULL) AND email IS NOT NULL
         ORDER BY LOWER(email), id
       ) r ON LOWER(r.email) = LOWER(gu.email)
       LEFT JOIN LATERAL (
         SELECT
           COALESCE(SUM(te.hours_worked), 0) as total_hours,
           COALESCE(SUM(CASE WHEN COALESCE(te.billable, true) = true THEN te.hours_worked ELSE 0 END), 0) as billable_hours
         FROM time_entries te
         WHERE te.resource_id = r.id
           AND te.entry_date >= NOW() - INTERVAL '${interval}'
           AND (te.is_deleted = false OR te.is_deleted IS NULL)
       ) te_agg ON true
       LEFT JOIN LATERAL (
         SELECT MAX(te2.entry_date) as entry_date
         FROM time_entries te2
         WHERE te2.resource_id = r.id
           AND (te2.is_deleted = false OR te2.is_deleted IS NULL)
       ) last_te ON true
       LEFT JOIN (
         SELECT resource_email,
           COUNT(*) AS zoom_call_count,
           COUNT(*) FILTER (WHERE matched_contact_id IS NOT NULL OR matched_company_id IS NOT NULL) AS zoom_client_call_count,
           COALESCE(SUM(duration_seconds), 0) AS zoom_call_duration_seconds
         FROM zoom_calls
         WHERE start_time >= NOW() - INTERVAL '${interval}'
           AND call_status = 'completed'
           AND COALESCE(duration_seconds, 0) > 0
         GROUP BY resource_email
       ) zc ON LOWER(r.email) = LOWER(zc.resource_email)
       LEFT JOIN (
         SELECT host_email,
           COUNT(*) AS zoom_meeting_count,
           COUNT(*) FILTER (WHERE has_client_attendees = true) AS zoom_client_meeting_count
         FROM zoom_meetings
         WHERE start_time >= NOW() - INTERVAL '${interval}'
         GROUP BY host_email
       ) zm ON LOWER(r.email) = LOWER(zm.host_email)
       LEFT JOIN LATERAL (
         SELECT
           COUNT(*) FILTER (WHERE LOWER(mm.sender_address) = LOWER(gu.email) AND mm.direction IN ('outbound', 'internal')) AS emails_sent,
           COUNT(*) FILTER (WHERE LOWER(mm.recipient_address) = LOWER(gu.email) AND mm.direction IN ('inbound', 'internal') AND mm.status IN ('archived', 'accepted')) AS emails_received
         FROM mimecast_messages mm
         WHERE (LOWER(mm.sender_address) = LOWER(gu.email) OR LOWER(mm.recipient_address) = LOWER(gu.email))
           AND mm.sent_datetime >= NOW() - INTERVAL '${interval}'
       ) mc ON true
       WHERE gu.account_enabled = true
         AND LOWER(gu.email) LIKE '%@wulfconsulting.%'
         AND LOWER(gu.email) NOT LIKE '%#ext#%'
         AND NOT (
           es.user_email IS NOT NULL
           AND COALESCE(es.emails_received, 0) = 0
           AND COALESCE(es.teams_chat_messages, 0) = 0
           AND COALESCE(es.teams_meetings_attended, 0) = 0
           AND COALESCE(es.teams_calls, 0) = 0
         )
       ORDER BY ${sortCol} ${order} NULLS LAST
       LIMIT $3 OFFSET $4`,
      [period, latestDate, pageSize, offset]
    );

    const users = usersResult.rows.map(row => ({
      graphUserId: row.graph_user_id,
      displayName: row.display_name,
      email: row.email,
      jobTitle: row.job_title,
      department: row.department,
      autotaskResourceId: row.autotask_resource_id,
      hoursWorked: parseFloat(row.hours_worked),
      billableHours: parseFloat(row.billable_hours),
      teamsMessages: parseInt(row.teams_chat_messages) + parseInt(row.teams_private_messages),
      teamsCallCount: parseInt(row.teams_calls),
      meetingsAttended: parseInt(row.teams_meetings_attended),
      meetingsOrganized: parseInt(row.teams_meetings_organized),
      emailsSent: parseInt(row.emails_sent),
      emailsReceived: parseInt(row.emails_received),
      audioDurationSeconds: parseInt(row.audio_duration_seconds),
      meetingDurationSeconds: parseInt(row.meeting_duration_seconds),
      meetingsWithExternal: parseInt(row.meetings_with_external),
      lastActivity: row.last_active,
      zoomCallCount: parseInt(row.zoom_call_count),
      zoomClientCallCount: parseInt(row.zoom_client_call_count),
      zoomCallDurationSeconds: parseInt(row.zoom_call_duration_seconds),
      zoomMeetingCount: parseInt(row.zoom_meeting_count),
      zoomClientMeetingCount: parseInt(row.zoom_client_meeting_count),
    }));

    return NextResponse.json({
      users,
      pagination: { total, page, pageSize, totalPages: Math.ceil(total / pageSize) },
    });
  } catch (error) {
    console.error('[ENGAGEMENT-USERS] Error:', error);
    return NextResponse.json({ error: 'Failed to fetch engagement users' }, { status: 500 });
  }
}
