/**
 * GET /api/pax8/companies
 *   Returns a paginated, sortable, searchable list of PAX8 companies with
 *   their matched Autotask company name and active subscription count.
 *   Query params:
 *     limit  (default 50, max 200)
 *     offset (default 0)
 *     sort   (name | status | city | country | subscriptions | match)
 *     order  (asc | desc, default asc)
 *     search (matches pc.name via ILIKE)
 */

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

interface CompanyRow {
  id: string;
  name: string;
  status: string | null;
  city: string | null;
  state_or_province: string | null;
  country: string | null;
  autotask_company_id: string | null;
  match_confidence: string | null;
  match_method: string | null;
  matched_company_name: string | null;
  active_subscription_count: string;
}

// Whitelisted sort columns — never interpolate the raw `sort` query param
// into SQL (T-14-04).
const SORT_COLUMNS: Record<string, string> = {
  name: 'pc.name',
  status: 'pc.status',
  city: 'pc.city',
  country: 'pc.country',
  subscriptions: 'active_subscription_count',
  match: 'pc.match_method',
};

export async function GET(request: NextRequest) {
  const { error } = await requireAuth();
  if (error) return error;

  try {
    const url = request.nextUrl;
    const limit = Math.min(parseInt(url.searchParams.get('limit') ?? '50', 10) || 50, 200);
    const offset = Math.max(parseInt(url.searchParams.get('offset') ?? '0', 10) || 0, 0);
    const sortParam = url.searchParams.get('sort') ?? '';
    const orderParam = url.searchParams.get('order') ?? '';
    const search = url.searchParams.get('search');

    const sortColumn = SORT_COLUMNS[sortParam] ?? SORT_COLUMNS.name;
    const sortOrder = orderParam.toLowerCase() === 'desc' ? 'DESC' : 'ASC';

    const params: unknown[] = [limit, offset];
    let searchFilter = '';
    if (search) {
      params.push(`%${search}%`);
      searchFilter = `AND pc.name ILIKE $${params.length}`;
    }

    const companies = await postgresClient.query<CompanyRow>(
      `SELECT pc.id, pc.name, pc.status, pc.city, pc.state_or_province, pc.country,
              pc.autotask_company_id::text AS autotask_company_id,
              pc.match_confidence::text AS match_confidence, pc.match_method,
              c.company_name AS matched_company_name,
              (SELECT count(*) FROM pax8_subscriptions s
                WHERE s.pax8_company_id = pc.id AND s.is_deleted = false
                  AND s.status = 'Active')::text AS active_subscription_count
         FROM pax8_companies pc
         LEFT JOIN companies c ON c.id = pc.autotask_company_id
        WHERE pc.is_deleted = false
          ${searchFilter}
        ORDER BY ${sortColumn} ${sortOrder}
        LIMIT $1 OFFSET $2`,
      params
    );

    const totalParams: unknown[] = [];
    let totalSearchFilter = '';
    if (search) {
      totalParams.push(`%${search}%`);
      totalSearchFilter = `AND pc.name ILIKE $${totalParams.length}`;
    }
    const totalRes = await postgresClient.query<{ count: string }>(
      `SELECT COUNT(*)::text AS count
         FROM pax8_companies pc
        WHERE pc.is_deleted = false ${totalSearchFilter}`,
      totalParams
    );
    const total = parseInt(totalRes.rows[0]?.count ?? '0', 10);

    const items = companies.rows.map((row) => ({
      id: row.id,
      name: row.name,
      status: row.status,
      city: row.city,
      stateOrProvince: row.state_or_province,
      country: row.country,
      autotaskCompanyId: row.autotask_company_id !== null ? Number(row.autotask_company_id) : null,
      matchConfidence: row.match_confidence !== null ? Number(row.match_confidence) : null,
      matchMethod: row.match_method,
      matchedCompanyName: row.matched_company_name,
      activeSubscriptionCount: Number(row.active_subscription_count),
    }));

    return NextResponse.json({ items, total, limit, offset });
  } catch (err) {
    console.error('Failed to fetch PAX8 companies:', err);
    return NextResponse.json(
      { error: err instanceof Error ? err.message : 'Failed to fetch PAX8 companies' },
      { status: 500 }
    );
  }
}
