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

interface MonthData {
  month: string;
  hoursWorked: number;
  billableHours: number;
  daysWorked: number;
  teamsMessages: number;
  teamsPrivateMessages: number;
  teamsCalls: number;
  meetingsAttended: number;
  meetingsOrganized: number;
  emailsSent: number;
  emailsReceived: number;
  totalMeetings: number;
  clientMeetings: number;
  meetingDurationMinutes: number;
  zoomCalls: number;
  zoomClientCalls: number;
}

export async function GET(
  _request: NextRequest,
  { params }: { params: Promise<{ userId: string }> }
) {
  const { userId } = await params;

  try {
    const userResult = await postgresClient.query(
      `SELECT gu.*,
              (SELECT r2.id FROM resources r2
               WHERE LOWER(r2.email) = LOWER(gu.email)
                 AND (r2.is_deleted = false OR r2.is_deleted IS NULL)
               ORDER BY (SELECT MAX(te.entry_date) FROM time_entries te WHERE te.resource_id = r2.id AND (te.is_deleted = false OR te.is_deleted IS NULL)) DESC NULLS LAST
               LIMIT 1) as autotask_resource_id
       FROM graph_users gu
       WHERE gu.id = $1`,
      [userId]
    );

    if (userResult.rows.length === 0) {
      return NextResponse.json({ error: 'User not found' }, { status: 404 });
    }

    const user = userResult.rows[0];

    // Daily time entries for the past 365 days
    const dailyResult = user.autotask_resource_id
      ? await postgresClient.query(
          `SELECT
             TO_CHAR(entry_date, 'YYYY-MM-DD') as date,
             SUM(hours_worked) as hours_worked,
             SUM(CASE WHEN COALESCE(billable, true) = true THEN hours_worked ELSE 0 END) as billable_hours
           FROM time_entries
           WHERE resource_id = $1
             AND (is_deleted = false OR is_deleted IS NULL)
             AND entry_date >= NOW() - INTERVAL '365 days'
           GROUP BY TO_CHAR(entry_date, 'YYYY-MM-DD')
           ORDER BY date`,
          [user.autotask_resource_id]
        )
      : null;

    // Monthly time entries for the past 12 months
    const monthlyHoursResult = user.autotask_resource_id
      ? await postgresClient.query(
          `SELECT
             TO_CHAR(DATE_TRUNC('month', entry_date), 'YYYY-MM') as month,
             SUM(hours_worked) as hours_worked,
             SUM(CASE WHEN COALESCE(billable, true) = true THEN hours_worked ELSE 0 END) as billable_hours,
             COUNT(DISTINCT TO_CHAR(entry_date, 'YYYY-MM-DD')) as days_worked
           FROM time_entries
           WHERE resource_id = $1
             AND (is_deleted = false OR is_deleted IS NULL)
             AND entry_date >= DATE_TRUNC('month', NOW() - INTERVAL '11 months')
           GROUP BY DATE_TRUNC('month', entry_date)
           ORDER BY month`,
          [user.autotask_resource_id]
        )
      : null;

    // Monthly engagement snapshots — latest D30 per calendar month
    const monthlySnapshotsResult = await postgresClient.query(
      `SELECT DISTINCT ON (TO_CHAR(period_end, 'YYYY-MM'))
         TO_CHAR(period_end, 'YYYY-MM') as month,
         teams_chat_messages,
         teams_private_messages,
         teams_calls,
         teams_meetings_attended,
         teams_meetings_organized,
         emails_sent,
         emails_received
       FROM engagement_snapshots
       WHERE LOWER(user_email) = LOWER($1)
         AND period_type = 'D30'
         AND period_end >= NOW() - INTERVAL '13 months'
       ORDER BY TO_CHAR(period_end, 'YYYY-MM'), period_end DESC`,
      [user.email]
    );

    // Monthly Teams meetings
    let monthlyMeetingsResult = null;
    try {
      monthlyMeetingsResult = await postgresClient.query(
        `SELECT
           TO_CHAR(DATE_TRUNC('month', start_time), 'YYYY-MM') as month,
           COUNT(*) as total_meetings,
           SUM(CASE WHEN has_client_attendees THEN 1 ELSE 0 END) as client_meetings,
           SUM(COALESCE(duration_minutes, 0)) as total_duration_minutes
         FROM teams_meetings
         WHERE LOWER(user_email) = LOWER($1)
           AND start_time >= DATE_TRUNC('month', NOW() - INTERVAL '11 months')
         GROUP BY DATE_TRUNC('month', start_time)
         ORDER BY month`,
        [user.email]
      );
    } catch { /* table may not exist */ }

    // Monthly Zoom calls
    let monthlyZoomResult = null;
    if (isZoomConfigured()) {
      try {
        monthlyZoomResult = await postgresClient.query(
          `SELECT
             TO_CHAR(DATE_TRUNC('month', start_time), 'YYYY-MM') as month,
             COUNT(*) as call_count,
             SUM(CASE WHEN matched_company_id IS NOT NULL THEN 1 ELSE 0 END) as client_calls
           FROM zoom_calls
           WHERE LOWER(resource_email) = LOWER($1)
             AND call_status = 'completed'
             AND COALESCE(duration_seconds, 0) > 0
             AND start_time >= DATE_TRUNC('month', NOW() - INTERVAL '11 months')
           GROUP BY DATE_TRUNC('month', start_time)
           ORDER BY month`,
          [user.email]
        );
      } catch { /* table may not exist */ }
    }

    // Build a complete 12-month map
    const now = new Date();
    const monthMap = new Map<string, MonthData>();
    for (let i = 11; i >= 0; i--) {
      const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
      monthMap.set(key, {
        month: key,
        hoursWorked: 0,
        billableHours: 0,
        daysWorked: 0,
        teamsMessages: 0,
        teamsPrivateMessages: 0,
        teamsCalls: 0,
        meetingsAttended: 0,
        meetingsOrganized: 0,
        emailsSent: 0,
        emailsReceived: 0,
        totalMeetings: 0,
        clientMeetings: 0,
        meetingDurationMinutes: 0,
        zoomCalls: 0,
        zoomClientCalls: 0,
      });
    }

    for (const row of monthlyHoursResult?.rows ?? []) {
      const m = monthMap.get(row.month);
      if (m) {
        m.hoursWorked = parseFloat(row.hours_worked ?? 0);
        m.billableHours = parseFloat(row.billable_hours ?? 0);
        m.daysWorked = parseInt(row.days_worked ?? 0);
      }
    }

    for (const row of monthlySnapshotsResult.rows) {
      const m = monthMap.get(row.month);
      if (m) {
        m.teamsMessages = parseInt(row.teams_chat_messages ?? 0);
        m.teamsPrivateMessages = parseInt(row.teams_private_messages ?? 0);
        m.teamsCalls = parseInt(row.teams_calls ?? 0);
        m.meetingsAttended = parseInt(row.teams_meetings_attended ?? 0);
        m.meetingsOrganized = parseInt(row.teams_meetings_organized ?? 0);
        m.emailsSent = parseInt(row.emails_sent ?? 0);
        m.emailsReceived = parseInt(row.emails_received ?? 0);
      }
    }

    for (const row of monthlyMeetingsResult?.rows ?? []) {
      const m = monthMap.get(row.month);
      if (m) {
        m.totalMeetings = parseInt(row.total_meetings ?? 0);
        m.clientMeetings = parseInt(row.client_meetings ?? 0);
        m.meetingDurationMinutes = parseInt(row.total_duration_minutes ?? 0);
      }
    }

    for (const row of monthlyZoomResult?.rows ?? []) {
      const m = monthMap.get(row.month);
      if (m) {
        m.zoomCalls = parseInt(row.call_count ?? 0);
        m.zoomClientCalls = parseInt(row.client_calls ?? 0);
      }
    }

    return NextResponse.json({
      user: {
        id: user.id,
        displayName: user.display_name,
        email: user.email,
        jobTitle: user.job_title,
        department: user.department,
        autotaskResourceId: user.autotask_resource_id,
      },
      daily: (dailyResult?.rows ?? []).map(r => ({
        date: r.date,
        hoursWorked: parseFloat(r.hours_worked ?? 0),
        billableHours: parseFloat(r.billable_hours ?? 0),
      })),
      monthly: Array.from(monthMap.values()),
    });
  } catch (error) {
    console.error('[ENGAGEMENT-HISTORY] Error:', error);
    return NextResponse.json({ error: 'Failed to fetch history' }, { status: 500 });
  }
}
