/**
 * Admin API for Publishing Integrity visibility.
 *
 * GET  /api/admin/publishing-integrity/games/:gameId
 * GET  /api/admin/publishing-integrity/players/:playerId
 * GET  /api/admin/publishing-integrity/suppressions
 * GET  /api/admin/publishing-integrity/audit-log
 * GET  /api/admin/publishing-integrity/freshness/:league/:gameId
 * POST /api/admin/publishing-integrity/reprocess/:gameId
 */

import { Router, Request, Response } from 'express';
import { authMiddleware } from '../middleware/auth';
import { auditAdminAccess, requireAdminAccess } from '../middleware/admin';
import pool from '../db';

const router = Router();

router.use(authMiddleware, requireAdminAccess, auditAdminAccess('publishing-integrity'));

// GET /api/admin/publishing-integrity/games/:gameId
router.get('/games/:gameId', async (req: Request, res: Response) => {
  const { gameId } = req.params;

  try {
    // Get game info
    const { rows: gameRows } = await pool.query(
      'SELECT event_id, league, home_team, away_team, starts_at, status FROM rm_events WHERE event_id = $1',
      [gameId]
    );

    // Get all prop eligibilities
    const { rows: eligRows } = await pool.query(
      'SELECT * FROM pi_prop_eligibility WHERE game_id = $1 ORDER BY player_name',
      [gameId]
    );

    // Get recent audit entries
    const { rows: auditRows } = await pool.query(
      'SELECT * FROM pi_publish_audit_log WHERE game_id = $1 ORDER BY acted_at DESC LIMIT 50',
      [gameId]
    );

    // Summary
    const states: Record<string, number> = {};
    for (const e of eligRows) {
      const vs = e.validation_state || 'UNKNOWN';
      states[vs] = (states[vs] || 0) + 1;
    }

    res.json({
      game: gameRows[0] || null,
      summary: {
        totalProps: eligRows.length,
        states,
        publishable: eligRows.filter((e: any) => e.publish_allowed).length,
        suppressed: eligRows.filter((e: any) => !e.publish_allowed).length,
      },
      eligibilities: eligRows,
      recentAudit: auditRows,
    });
  } catch (err) {
    console.error('PI game status error:', err);
    res.status(500).json({ error: 'Failed to fetch game integrity status' });
  }
});

// GET /api/admin/publishing-integrity/players/:playerId
router.get('/players/:playerId', async (req: Request, res: Response) => {
  const { playerId } = req.params;

  try {
    const { rows } = await pool.query(
      'SELECT * FROM pi_prop_eligibility WHERE player_id = $1 ORDER BY created_at DESC',
      [playerId]
    );
    res.json({ playerId, totalRecords: rows.length, records: rows });
  } catch (err) {
    console.error('PI player status error:', err);
    res.status(500).json({ error: 'Failed to fetch player integrity status' });
  }
});

// GET /api/admin/publishing-integrity/suppressions?league=nba&limit=100
router.get('/suppressions', async (req: Request, res: Response) => {
  const league = req.query.league as string || null;
  const limit = parseInt(req.query.limit as string) || 100;

  try {
    let query = 'SELECT * FROM pi_prop_eligibility WHERE publish_allowed = false';
    const params: any[] = [];
    if (league) {
      params.push(league);
      query += ` AND league = $${params.length}`;
    }
    params.push(limit);
    query += ` ORDER BY updated_at DESC LIMIT $${params.length}`;

    const { rows } = await pool.query(query, params);
    res.json({ total: rows.length, leagueFilter: league, suppressions: rows });
  } catch (err) {
    console.error('PI suppressions error:', err);
    res.status(500).json({ error: 'Failed to fetch suppressions' });
  }
});

// GET /api/admin/publishing-integrity/audit-log?limit=200
router.get('/audit-log', async (req: Request, res: Response) => {
  const limit = parseInt(req.query.limit as string) || 200;

  try {
    const { rows } = await pool.query(
      'SELECT * FROM pi_publish_audit_log ORDER BY acted_at DESC LIMIT $1',
      [limit]
    );
    res.json({ total: rows.length, entries: rows });
  } catch (err) {
    console.error('PI audit log error:', err);
    res.status(500).json({ error: 'Failed to fetch audit log' });
  }
});

// GET /api/admin/publishing-integrity/freshness/:league/:gameId
router.get('/freshness/:league/:gameId', async (req: Request, res: Response) => {
  const { league, gameId } = req.params;

  try {
    const { rows } = await pool.query(
      'SELECT * FROM pi_prop_eligibility WHERE game_id = $1',
      [gameId]
    );

    if (rows.length === 0) {
      res.json({ gameId, status: 'no_data' });
      return;
    }

    // Find most recent timestamps
    let latestRoster: Date | null = null;
    let latestAvail: Date | null = null;
    let latestLineup: Date | null = null;

    for (const r of rows) {
      if (r.roster_verified_at && (!latestRoster || r.roster_verified_at > latestRoster))
        latestRoster = r.roster_verified_at;
      if (r.availability_verified_at && (!latestAvail || r.availability_verified_at > latestAvail))
        latestAvail = r.availability_verified_at;
      if (r.lineup_verified_at && (!latestLineup || r.lineup_verified_at > latestLineup))
        latestLineup = r.lineup_verified_at;
    }

    const now = new Date();
    const ageMin = (ts: Date | null) => ts ? Math.round((now.getTime() - ts.getTime()) / 60000) : null;

    res.json({
      gameId,
      league,
      propCount: rows.length,
      freshness: {
        roster: { verifiedAt: latestRoster, ageMinutes: ageMin(latestRoster) },
        availability: { verifiedAt: latestAvail, ageMinutes: ageMin(latestAvail) },
        lineup: { verifiedAt: latestLineup, ageMinutes: ageMin(latestLineup) },
      },
    });
  } catch (err) {
    console.error('PI freshness error:', err);
    res.status(500).json({ error: 'Failed to fetch freshness data' });
  }
});

// POST /api/admin/publishing-integrity/reprocess/:gameId
router.post('/reprocess/:gameId', async (req: Request, res: Response) => {
  const { gameId } = req.params;

  try {
    // Clear existing eligibilities for this game to force reprocessing
    await pool.query(
      'DELETE FROM pi_prop_eligibility WHERE game_id = $1',
      [gameId]
    );

    // Log the reprocess request
    await pool.query(
      `INSERT INTO pi_publish_audit_log (run_id, game_id, player_id, action, validation_state)
       VALUES ('manual', $1, 'ALL', 'REPROCESSED', 'MANUAL_REVIEW_REQUIRED')`,
      [gameId]
    );

    res.json({ success: true, message: `Cleared eligibility data for ${gameId}. Next scheduled run will reprocess.` });
  } catch (err) {
    console.error('PI reprocess error:', err);
    res.status(500).json({ error: 'Failed to trigger reprocess' });
  }
});

// GET /api/admin/publishing-integrity/summary — dashboard overview
router.get('/summary', async (req: Request, res: Response) => {
  try {
    const [
      { rows: stateRows },
      { rows: recentSupp },
      { rows: recentAudit },
      { rows: flagRows },
      { rows: unresolvedEventRows },
      { rows: stalePendingOrderRows },
    ] = await Promise.all([
      pool.query(`
        SELECT league, validation_state, COUNT(*) as count
        FROM pi_prop_eligibility
        WHERE created_at > NOW() - INTERVAL '24 hours'
        GROUP BY league, validation_state
        ORDER BY league, validation_state
      `),
      pool.query(`
        SELECT COUNT(*) as count FROM pi_prop_eligibility
        WHERE publish_allowed = false AND updated_at > NOW() - INTERVAL '24 hours'
      `),
      pool.query(`
        SELECT action, COUNT(*) as count FROM pi_publish_audit_log
        WHERE acted_at > NOW() - INTERVAL '24 hours'
        GROUP BY action
      `),
      pool.query(`
        SELECT flag_name, flag_value FROM pi_feature_flags ORDER BY flag_name
      `),
      pool.query(`
        SELECT COUNT(*)::int AS count
        FROM rm_events
        WHERE starts_at < NOW() - INTERVAL '8 hours'
          AND COALESCE(status, 'scheduled') NOT IN ('ended', 'final', 'closed', 'cancelled', 'postponed')
      `),
      pool.query(`
        SELECT COUNT(*)::int AS count
        FROM rm_pending_orders po
        WHERE po.status = 'pending'
          AND po.created_at < NOW() - INTERVAL '2 hours'
          AND COALESCE(po.transaction_id, '') = ''
          AND po.completed_at IS NULL
          AND NOT EXISTS (
            SELECT 1
            FROM rm_purchases p
            WHERE p.stripe_session_id = po.invoice_number
          )
      `),
    ]);

    res.json({
      last24h: {
        byLeagueState: stateRows,
        totalSuppressed: parseInt(recentSupp[0]?.count || '0'),
        auditActions: recentAudit,
      },
      featureFlags: flagRows,
      operations: {
        staleUnresolvedEvents: Number(unresolvedEventRows[0]?.count || 0),
        stalePendingOrders: Number(stalePendingOrderRows[0]?.count || 0),
      },
    });
  } catch (err) {
    console.error('PI summary error:', err);
    res.status(500).json({ error: 'Failed to fetch summary' });
  }
});

export default router;
