/**
 * OCDS 1.1.5 Party — single entity (buyer or supplier) with aggregate stats.
 * GET /api/ocds/parties/{id}    where id = "RO-CUI-{cui}" or just "{cui}"
 *
 * Returns a custom-extended Party object with `stats` (vreaudigital extension):
 *   { contractsAsBuyer, contractsAsSupplier, totalValueAsBuyer, totalValueAsSupplier,
 *     firstSeen, lastSeen, topCpvDivisions[], counties[] }
 */
import type { APIRoute } from 'astro';
import { query } from '../../../../lib/db.js';
import { publicOrigin } from '../../../../lib/public-url.js';

export const prerender = false;

interface PartyRow {
  cui: string;
  name: string | null;
  county: string | null;
  siruta: string | null;
  contracts_as_buyer: number;
  contracts_as_supplier: number;
  total_as_buyer: string;
  total_as_supplier: string;
  first_seen: string | null;
  last_seen: string | null;
  buyer_address: string | null;
  buyer_email: string | null;
  buyer_url: string | null;
  authority_type: string | null;
  is_sme: boolean | null;
  supplier_address: string | null;
}

export const GET: APIRoute = async ({ params, url, request }) => {
  const idRaw = params.id as string;
  // Normalize: strip "RO-CUI-" prefix and "RO " from CUI
  const cui = idRaw.replace(/^RO-CUI-/, '').replace(/^RO\s*/i, '').replace(/\s+/g, '').trim();
  if (!cui) {
    return new Response(JSON.stringify({ error: 'Invalid party id' }), {
      status: 400,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  try {
    // Aggregate as buyer + as supplier in a single query
    const result = await query<PartyRow>(`
      WITH buyer_agg AS (
        SELECT
          a.authority_cui AS cui,
          MIN(a.authority_name) AS name,
          MIN(cl.county) AS county,
          MIN(cl.siruta) AS siruta,
          MIN(a.authority_address) AS buyer_address,
          MIN(a.authority_email) AS buyer_email,
          MIN(a.authority_url) AS buyer_url,
          MIN(a.authority_type) AS authority_type,
          COUNT(*)::int AS contracts_as_buyer,
          COALESCE(SUM(a.awarded_value), 0)::numeric(20,2) AS total_as_buyer,
          MIN(a.publication_date) AS first_seen_buyer,
          MAX(a.publication_date) AS last_seen_buyer
        FROM seap.announcements a
        LEFT JOIN seap.cui_location cl ON cl.cui = a.authority_cui
        WHERE a.authority_cui = $1
        GROUP BY a.authority_cui
      ),
      supplier_agg AS (
        SELECT
          $1::text AS cui,
          MIN(a.supplier_name) AS name,
          MIN(cl.county) AS county,
          MIN(cl.siruta) AS siruta,
          MIN(a.supplier_address) AS supplier_address,
          BOOL_OR(a.supplier_is_sme) AS is_sme,
          COUNT(*)::int AS contracts_as_supplier,
          COALESCE(SUM(a.awarded_value), 0)::numeric(20,2) AS total_as_supplier,
          MIN(a.publication_date) AS first_seen_supplier,
          MAX(a.publication_date) AS last_seen_supplier
        FROM seap.announcements a
        LEFT JOIN seap.cui_location cl ON cl.cui = $1
        WHERE (a.supplier_cui = $1 OR a.supplier_cui = 'RO ' || $1 OR a.supplier_cui = 'RO' || $1)
      )
      SELECT
        $1::text AS cui,
        COALESCE(b.name, s.name) AS name,
        COALESCE(b.county, s.county) AS county,
        COALESCE(b.siruta, s.siruta) AS siruta,
        b.buyer_address,
        b.buyer_email,
        b.buyer_url,
        b.authority_type,
        s.is_sme,
        s.supplier_address,
        COALESCE(b.contracts_as_buyer, 0) AS contracts_as_buyer,
        COALESCE(s.contracts_as_supplier, 0) AS contracts_as_supplier,
        COALESCE(b.total_as_buyer, 0) AS total_as_buyer,
        COALESCE(s.total_as_supplier, 0) AS total_as_supplier,
        LEAST(b.first_seen_buyer, s.first_seen_supplier) AS first_seen,
        GREATEST(b.last_seen_buyer, s.last_seen_supplier) AS last_seen
      FROM (SELECT 1) AS dummy
      LEFT JOIN buyer_agg b ON true
      LEFT JOIN supplier_agg s ON true
    `, [cui]);

    const row = result.rows[0];
    if (!row || (row.contracts_as_buyer === 0 && row.contracts_as_supplier === 0)) {
      return new Response(JSON.stringify({ error: 'Party not found in any role' }), {
        status: 404,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    const roles: string[] = [];
    if (Number(row.contracts_as_buyer) > 0) roles.push('buyer', 'procuringEntity');
    if (Number(row.contracts_as_supplier) > 0) roles.push('supplier', 'tenderer');

    // Top CPV divisions for narrative
    const cpvResult = await query<{ cpv_division: string; cpv_division_name: string; contracts: number; total_value: string }>(`
      SELECT
        a.cpv_division,
        c.name_ro AS cpv_division_name,
        COUNT(*)::int AS contracts,
        COALESCE(SUM(a.awarded_value), 0)::numeric(20,2) AS total_value
      FROM seap.announcements a
      LEFT JOIN seap.cpv_codes c ON c.code = a.cpv_division
      WHERE (a.authority_cui = $1
             OR a.supplier_cui = $1
             OR a.supplier_cui = 'RO ' || $1
             OR a.supplier_cui = 'RO' || $1)
        AND a.cpv_division IS NOT NULL
      GROUP BY a.cpv_division, c.name_ro
      ORDER BY total_value DESC NULLS LAST
      LIMIT 10
    `, [cui]);

    const party = {
      id: `RO-CUI-${cui}`,
      name: row.name,
      identifier: {
        scheme: 'RO-CUI',
        id: cui,
        legalName: row.name,
      },
      roles,
      address: (row.buyer_address || row.supplier_address || row.county) ? {
        streetAddress: row.buyer_address || row.supplier_address || undefined,
        region: row.county || undefined,
        countryName: 'Romania',
      } : undefined,
      contactPoint: (row.buyer_email || row.buyer_url) ? {
        email: row.buyer_email || undefined,
        url: row.buyer_url || undefined,
      } : undefined,
      details: {
        scale: row.is_sme === true ? 'sme' : (row.is_sme === false ? 'large' : undefined),
        siruta: row.siruta || undefined,
        authorityType: row.authority_type || undefined,
      },
      // vreaudigital extension — not standard OCDS but useful
      stats: {
        firstSeen: row.first_seen,
        lastSeen: row.last_seen,
        asBuyer: {
          contracts: Number(row.contracts_as_buyer),
          totalValue: Number(row.total_as_buyer),
          currency: 'RON',
        },
        asSupplier: {
          contracts: Number(row.contracts_as_supplier),
          totalValue: Number(row.total_as_supplier),
          currency: 'RON',
        },
        topCpvDivisions: cpvResult.rows.map((c) => ({
          division: c.cpv_division,
          name: c.cpv_division_name,
          contracts: Number(c.contracts),
          totalValue: Number(c.total_value),
        })),
      },
    };

    const requestUri = `${publicOrigin(request, url)}${url.pathname}${url.search}`;
    return new Response(JSON.stringify({
      uri: requestUri,
      version: '1.1',
      publishedDate: new Date().toISOString(),
      publisher: { name: 'vreaudigital.ro', uri: 'https://vreaudigital.ro' },
      license: 'https://creativecommons.org/licenses/by/4.0/',
      party,
    }, null, 2), {
      status: 200,
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        'Access-Control-Allow-Origin': '*',
        'Cache-Control': 'public, max-age=600, s-maxage=3600',
      },
    });
  } catch (err: any) {
    console.error('[/api/ocds/parties/:id]', err);
    return new Response(JSON.stringify({ error: 'Internal server error' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
};
