/**
 * GET /api/dashboard/overview
 *   Single round-trip backing the new dashboard. All queries run in parallel.
 *
 *   today          — KPI snapshot: opened, resolved, open total, SLA breaches
 *   attention      — counts that should pull a human's eyes
 *   observations   — recent device_observations (loglift et al.)
 *   audits         — recent endpoint_audits
 *   syncHealth     — per-schedule last_run / last_status (consumed by /status)
 *   stats          — small footer: companies, CIs, xref linkage
 */

import { NextResponse } from 'next/server';
import { requireAuth } from '@/lib/auth-utils';
import postgresClient from '@/lib/services/postgres-client';
import { getUserTimezone } from '@/lib/services/user-timezone';

export async function GET() {
  const { session, error } = await requireAuth();
  if (error) return error;
  const tz = getUserTimezone(session);

  type Counts = { count: string };

  const [
    todayRes,
    yesterdayOpenedRes,
    last7AvgResolvedRes,
    linkConflictsRes,
    itglueUnlinkedRes,
    s1UnmappedRes,
    schedulesRes,
    observationsRes,
    auditsRes,
    syncHealthRes,
    companiesRes,
    ciRes,
    xrefRes,
  ] = await Promise.all([
    /* today snapshot — single row, all four KPIs.
       Day-boundary counts are anchored to the calling user's tz via $1.
       The `due_date_time < NOW()` clause stays as-is (rolling-now SLA check
       is timezone-independent). */
    postgresClient.query<{
      opened_today: string;
      resolved_today: string;
      open_total: string;
      sla_breaches: string;
    }>(
      `
      SELECT
        COUNT(*) FILTER (WHERE ((create_date    AT TIME ZONE 'UTC') AT TIME ZONE $1)::date = (NOW() AT TIME ZONE $1)::date)::text  AS opened_today,
        COUNT(*) FILTER (WHERE ((completed_date AT TIME ZONE 'UTC') AT TIME ZONE $1)::date = (NOW() AT TIME ZONE $1)::date)::text  AS resolved_today,
        COUNT(*) FILTER (WHERE completed_date IS NULL)::text                                                                                                AS open_total,
        COUNT(*) FILTER (
          WHERE completed_date IS NULL
            AND due_date_time IS NOT NULL
            AND due_date_time < NOW()
        )::text                                                                                                                                              AS sla_breaches
      FROM tickets
      WHERE (is_deleted = false OR is_deleted IS NULL)
        AND company_id NOT IN (SELECT company_id FROM company_scope WHERE in_scope = false)
    `,
      [tz],
    ),
    /* yesterday's opened count for the today-vs-yesterday delta (user-tz) */
    postgresClient.query<{ count: string }>(
      `
      SELECT COUNT(*)::text AS count
        FROM tickets
       WHERE ((create_date AT TIME ZONE 'UTC') AT TIME ZONE $1)::date = (NOW() AT TIME ZONE $1)::date - INTERVAL '1 day'
         AND (is_deleted = false OR is_deleted IS NULL)
         AND company_id NOT IN (SELECT company_id FROM company_scope WHERE in_scope = false)
    `,
      [tz],
    ),
    /* 7-day average resolved (excluding today) for the resolved delta (user-tz) */
    postgresClient.query<{ avg_resolved: string }>(
      `
      SELECT COALESCE(AVG(daily_count), 0)::text AS avg_resolved
        FROM (
          SELECT ((completed_date AT TIME ZONE 'UTC') AT TIME ZONE $1)::date AS d, COUNT(*) AS daily_count
            FROM tickets
           WHERE ((completed_date AT TIME ZONE 'UTC') AT TIME ZONE $1)::date >= (NOW() AT TIME ZONE $1)::date - INTERVAL '7 days'
             AND ((completed_date AT TIME ZONE 'UTC') AT TIME ZONE $1)::date <  (NOW() AT TIME ZONE $1)::date
             AND (is_deleted = false OR is_deleted IS NULL)
             AND company_id NOT IN (SELECT company_id FROM company_scope WHERE in_scope = false)
           GROUP BY ((completed_date AT TIME ZONE 'UTC') AT TIME ZONE $1)::date
        ) sub
    `,
      [tz],
    ),
    postgresClient.query<Counts>(
      `SELECT COUNT(*)::text AS count FROM device_link_review WHERE resolved_at IS NULL`
    ),
    postgresClient.query<Counts>(
      `SELECT COUNT(*)::text AS count FROM device_external_ids WHERE source = 'itglue' AND configuration_item_id IS NULL`
    ),
    postgresClient.query<Counts>(
      `SELECT COUNT(*)::text AS count FROM device_external_ids WHERE source = 's1' AND configuration_item_id IS NULL`
    ),
    postgresClient.query<{ enabled: string; total: string }>(
      `SELECT
         COUNT(*) FILTER (WHERE is_enabled)::text AS enabled,
         COUNT(*)::text AS total
         FROM sync_schedules`
    ),
    postgresClient.query<{
      id: string;
      kind: string;
      source: string;
      collected_at: string;
      hostname: string | null;
      company_name: string | null;
      run_id: string | null;
    }>(
      `SELECT o.id::text,
              o.kind, o.source,
              o.collected_at::text,
              ci.reference_title AS hostname,
              c.company_name,
              o.run_id
         FROM device_observations o
         LEFT JOIN configuration_items ci ON ci.id = o.configuration_item_id
         LEFT JOIN companies c ON c.id = ci.company_id
        ORDER BY o.collected_at DESC
        LIMIT 10`
    ),
    postgresClient.query<{
      id: string;
      generated_at: string;
      hostname: string | null;
      company_name: string | null;
      overall_score: string | null;
      field_gaps_count: string;
      status: string;
    }>(
      `SELECT a.id::text,
              a.generated_at::text,
              ci.reference_title AS hostname,
              c.company_name,
              a.overall_score::text,
              jsonb_array_length(COALESCE(a.field_gaps, '[]'::jsonb))::text AS field_gaps_count,
              a.status
         FROM endpoint_audits a
         LEFT JOIN configuration_items ci ON ci.id = a.configuration_item_id
         LEFT JOIN companies c ON c.id = ci.company_id
        ORDER BY a.generated_at DESC
        LIMIT 10`
    ),
    postgresClient.query<{
      id: string;
      name: string;
      sync_type: string;
      is_enabled: boolean;
      last_run: string | null;
      last_status: string | null;
      last_error: string | null;
      next_run: string | null;
    }>(
      `SELECT id, name, sync_type, is_enabled,
              last_run::text, last_status, last_error,
              next_run::text
         FROM sync_schedules
        ORDER BY name`
    ),
    postgresClient.query<Counts>(
      `SELECT COUNT(*)::text AS count FROM companies WHERE company_type = 1 AND is_active = true`
    ),
    postgresClient.query<Counts>(
      `SELECT COUNT(*)::text AS count FROM configuration_items WHERE is_deleted = false OR is_deleted IS NULL`
    ),
    postgresClient.query<{ total: string; linked: string }>(
      `SELECT COUNT(*)::text AS total,
              COUNT(*) FILTER (WHERE configuration_item_id IS NOT NULL)::text AS linked
         FROM device_external_ids`
    ),
  ]);

  const today = todayRes.rows[0];
  const yesterdayOpened = parseInt(yesterdayOpenedRes.rows[0]?.count ?? '0', 10);
  const last7Avg = parseFloat(last7AvgResolvedRes.rows[0]?.avg_resolved ?? '0');

  return NextResponse.json({
    today: {
      openedToday: parseInt(today?.opened_today ?? '0', 10),
      resolvedToday: parseInt(today?.resolved_today ?? '0', 10),
      openTotal: parseInt(today?.open_total ?? '0', 10),
      slaBreaches: parseInt(today?.sla_breaches ?? '0', 10),
      yesterdayOpened,
      last7DayAvgResolved: Math.round(last7Avg * 10) / 10,
    },
    attention: {
      linkConflicts: parseInt(linkConflictsRes.rows[0]?.count ?? '0', 10),
      itglueUnlinked: parseInt(itglueUnlinkedRes.rows[0]?.count ?? '0', 10),
      s1Unmapped: parseInt(s1UnmappedRes.rows[0]?.count ?? '0', 10),
      schedules: {
        enabled: parseInt(schedulesRes.rows[0]?.enabled ?? '0', 10),
        total: parseInt(schedulesRes.rows[0]?.total ?? '0', 10),
      },
    },
    observations: observationsRes.rows.map((r) => ({
      id: r.id,
      kind: r.kind,
      source: r.source,
      collectedAt: r.collected_at,
      hostname: r.hostname,
      companyName: r.company_name,
      runId: r.run_id,
    })),
    audits: auditsRes.rows.map((r) => ({
      id: r.id,
      generatedAt: r.generated_at,
      hostname: r.hostname,
      companyName: r.company_name,
      overallScore: r.overall_score === null ? null : Number(r.overall_score),
      fieldGapsCount: parseInt(r.field_gaps_count, 10),
      status: r.status,
    })),
    syncHealth: syncHealthRes.rows.map((r) => ({
      id: r.id,
      name: r.name,
      syncType: r.sync_type,
      isEnabled: r.is_enabled,
      lastRun: r.last_run,
      lastStatus: r.last_status,
      lastError: r.last_error,
      nextRun: r.next_run,
    })),
    stats: {
      activeCompanies: parseInt(companiesRes.rows[0]?.count ?? '0', 10),
      configurationItems: parseInt(ciRes.rows[0]?.count ?? '0', 10),
      xref: {
        total: parseInt(xrefRes.rows[0]?.total ?? '0', 10),
        linked: parseInt(xrefRes.rows[0]?.linked ?? '0', 10),
      },
    },
  });
}
