import { Router } from 'express';
import pool from '../db';
import { authMiddleware } from '../middleware/auth';
import { runCompliancePipeline, applyRewrite } from '../services/compliance/pipeline';
import { getActivePolicy, listPolicies, createPolicyVersion, activatePolicy, seedV2Policy } from '../services/compliance/policy';
import { scanContent } from '../services/compliance/scanner';
import { ContentPayload, RAINMAKER_PROPERTY_ID, COMPLIANCE_OFF_RESULT } from '../services/compliance/types';
import { isUuid } from '../lib/uuid';

const router = Router();

// POST /api/compliance/scan — run full compliance pipeline (property-scoped)
router.post('/scan', authMiddleware, async (req, res) => {
  try {
    const { propertyId, contentType, contentId, contentSource, fields, text } = req.body;

    // Support both { fields } and { text } payloads
    const resolvedFields = fields || (text ? { content: text } : null);

    if (!contentType || !resolvedFields || Object.keys(resolvedFields).length === 0) {
      return res.status(400).json({ error: 'contentType and fields (or text) are required' });
    }

    const pid = propertyId || RAINMAKER_PROPERTY_ID;

    // Property isolation: non-rainmaker returns immediate PASS
    if (pid !== RAINMAKER_PROPERTY_ID) {
      return res.json({
        ...COMPLIANCE_OFF_RESULT,
        propertyId: pid,
        note: 'compliance_off',
      });
    }

    const result = await runCompliancePipeline({
      propertyId: pid,
      contentType,
      contentId,
      contentSource,
      fields: resolvedFields,
    });

    // Map response to spec format
    res.json({
      ...result,
      riskScoreBefore: result.severityScore,
      riskScoreAfter: result.riskScoreAfter,
    });
  } catch (err: any) {
    console.error('[COMPLIANCE] Scan error:', err);
    res.status(500).json({ error: err.message });
  }
});

// POST /api/compliance/scan-only — scan without persisting (quick check)
router.post('/scan-only', authMiddleware, async (req, res) => {
  try {
    const { propertyId, fields } = req.body;

    // Property isolation
    if (propertyId && propertyId !== RAINMAKER_PROPERTY_ID) {
      return res.json({ status: 'PASS', severityScore: 0, findings: [], note: 'compliance_off' });
    }

    if (!fields) return res.status(400).json({ error: 'fields required' });

    const result = await scanContent(fields);
    res.json(result);
  } catch (err: any) {
    console.error('[COMPLIANCE] Scan-only error:', err);
    res.status(500).json({ error: err.message });
  }
});

// POST /api/compliance/apply — apply rewrite to source content
router.post('/apply', authMiddleware, async (req, res) => {
  try {
    const { propertyId, scanId, applyMode } = req.body;

    // Property isolation
    if (propertyId && propertyId !== RAINMAKER_PROPERTY_ID) {
      return res.status(400).json({ error: 'Compliance apply is only supported for rainmaker_web', ok: false });
    }

    if (!scanId || !applyMode) {
      return res.status(400).json({ error: 'scanId and applyMode required' });
    }

    const result = await applyRewrite(scanId, applyMode);
    res.json({ ...result, ok: result.success });
  } catch (err: any) {
    console.error('[COMPLIANCE] Apply error:', err);
    res.status(500).json({ error: err.message });
  }
});

// GET /api/compliance/scans — paginated scan list (rainmaker_web only)
router.get('/scans', async (req, res) => {
  try {
    const page = parseInt(req.query.page as string) || 1;
    const limit = 25;
    const offset = (page - 1) * limit;
    const status = req.query.status as string;
    const contentType = req.query.contentType as string;

    // Always scope to rainmaker_web
    let where = `WHERE property_id = $1`;
    const params: any[] = [RAINMAKER_PROPERTY_ID];
    let idx = 2;

    if (status) {
      where += ` AND final_status = $${idx++}`;
      params.push(status);
    }
    if (contentType) {
      where += ` AND content_type = $${idx++}`;
      params.push(contentType);
    }

    const countQ = await pool.query(`SELECT COUNT(*) FROM rm_compliance_scans ${where}`, params);
    const total = parseInt(countQ.rows[0].count);

    const { rows } = await pool.query(
      `SELECT id, content_id, content_type, content_source, policy_version,
              severity_score, risk_score_after, final_status, rewrite_attempted, rewrite_passed,
              applied_at, reviewed_by, created_at, property_id,
              jsonb_array_length(findings) AS findings_count
       FROM rm_compliance_scans ${where}
       ORDER BY created_at DESC
       LIMIT $${idx++} OFFSET $${idx}`,
      [...params, limit, offset]
    );

    res.json({ scans: rows, total, page, pages: Math.ceil(total / limit) });
  } catch (err: any) {
    console.error('[COMPLIANCE] List scans error:', err);
    res.status(500).json({ error: err.message });
  }
});

// GET /api/compliance/scans/:id — scan detail with findings
router.get('/scans/:id', async (req, res) => {
  try {
    if (!isUuid(req.params.id)) {
      return res.status(400).json({ error: 'Invalid scan id' });
    }

    const { rows: scans } = await pool.query(
      'SELECT * FROM rm_compliance_scans WHERE id = $1',
      [req.params.id]
    );
    if (scans.length === 0) return res.status(404).json({ error: 'Scan not found' });

    const { rows: hits } = await pool.query(
      'SELECT * FROM rm_compliance_rule_hits WHERE scan_id = $1 ORDER BY created_at',
      [req.params.id]
    );

    res.json({ scan: scans[0], ruleHits: hits });
  } catch (err: any) {
    console.error('[COMPLIANCE] Scan detail error:', err);
    res.status(500).json({ error: err.message });
  }
});

// GET /api/compliance/policies — all policy versions
router.get('/policies', async (_req, res) => {
  try {
    const policies = await listPolicies();
    res.json({ policies });
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

// GET /api/compliance/policies/active — current active policy
router.get('/policies/active', async (_req, res) => {
  try {
    const policy = await getActivePolicy();
    res.json({ policy });
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

// POST /api/compliance/policies — create new version (rainmaker_web only)
router.post('/policies', authMiddleware, async (req, res) => {
  try {
    const policy = await createPolicyVersion(req.body);
    res.json({ policy });
  } catch (err: any) {
    console.error('[COMPLIANCE] Create policy error:', err);
    res.status(500).json({ error: err.message });
  }
});

// POST /api/compliance/policies/:version/activate — activate version
router.post('/policies/:version/activate', authMiddleware, async (req, res) => {
  try {
    await activatePolicy(parseInt(req.params.version as string));
    res.json({ success: true });
  } catch (err: any) {
    console.error('[COMPLIANCE] Activate policy error:', err);
    res.status(500).json({ error: err.message });
  }
});

// POST /api/compliance/seed — seed v2 policy
router.post('/seed', authMiddleware, async (_req, res) => {
  try {
    const policy = await seedV2Policy();
    res.json({ policy });
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

// GET /api/compliance/analytics — rule hit analytics (rainmaker_web only)
router.get('/analytics', async (req, res) => {
  try {
    const days = parseInt(req.query.days as string) || 30;
    const since = new Date();
    since.setDate(since.getDate() - days);

    const [topRules, dailyVolume, statusBreakdown, sourceBreakdown] = await Promise.all([
      pool.query(
        `SELECT rule_id, COUNT(*) AS hit_count, MAX(severity) AS max_severity
         FROM rm_compliance_rule_hits rh
         JOIN rm_compliance_scans rs ON rh.scan_id = rs.id
         WHERE rh.created_at >= $1 AND rs.property_id = $2
         GROUP BY rule_id
         ORDER BY hit_count DESC
         LIMIT 10`,
        [since, RAINMAKER_PROPERTY_ID]
      ),
      pool.query(
        `SELECT DATE(created_at) AS day, final_status, COUNT(*) AS count
         FROM rm_compliance_scans
         WHERE created_at >= $1 AND property_id = $2
         GROUP BY DATE(created_at), final_status
         ORDER BY day DESC`,
        [since, RAINMAKER_PROPERTY_ID]
      ),
      pool.query(
        `SELECT final_status, COUNT(*) AS count
         FROM rm_compliance_scans
         WHERE created_at >= $1 AND property_id = $2
         GROUP BY final_status`,
        [since, RAINMAKER_PROPERTY_ID]
      ),
      pool.query(
        `SELECT content_source, COUNT(*) AS count
         FROM rm_compliance_scans
         WHERE created_at >= $1 AND property_id = $2
         GROUP BY content_source`,
        [since, RAINMAKER_PROPERTY_ID]
      ),
    ]);

    // Calculate auto-fixed count
    const { rows: autoFixed } = await pool.query(
      `SELECT COUNT(*) AS count FROM rm_compliance_scans
       WHERE created_at >= $1 AND property_id = $2 AND rewrite_attempted = TRUE AND rewrite_passed = TRUE`,
      [since, RAINMAKER_PROPERTY_ID]
    );

    res.json({
      topRules: topRules.rows,
      dailyVolume: dailyVolume.rows,
      statusBreakdown: statusBreakdown.rows,
      sourceBreakdown: sourceBreakdown.rows,
      autoFixedCount: parseInt(autoFixed[0].count),
    });
  } catch (err: any) {
    console.error('[COMPLIANCE] Analytics error:', err);
    res.status(500).json({ error: err.message });
  }
});

// POST /api/compliance/review — admin review a scan
router.post('/review', authMiddleware, async (req, res) => {
  try {
    const { scanId, reviewedBy, notes, action } = req.body;
    if (!scanId) return res.status(400).json({ error: 'scanId required' });

    // Verify scan is rainmaker_web
    const { rows: check } = await pool.query(
      'SELECT property_id FROM rm_compliance_scans WHERE id = $1',
      [scanId]
    );
    if (check.length > 0 && check[0].property_id !== RAINMAKER_PROPERTY_ID) {
      return res.status(400).json({ error: 'Reviews only supported for rainmaker_web scans' });
    }

    await pool.query(
      `UPDATE rm_compliance_scans SET
        reviewed_by = $1, reviewer_notes = $2, reviewed_at = NOW(),
        final_status = COALESCE($3, final_status)
       WHERE id = $4`,
      [reviewedBy || 'admin', notes || null, action || null, scanId]
    );

    res.json({ success: true });
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

export default router;
