import { Router, Request, Response } from 'express';
import { authMiddleware } from '../middleware/auth';
import pool from '../db';
import { sendClipperEmail } from '../services/email';

const router = Router();

const PANEL_ENABLED = () => process.env.FEATURE_CLIPPER_PANEL === 'true';
const ACTIONS_ENABLED = () => process.env.FEATURE_CLIPPING_ACTIONS === 'true';

const MAX_CLIPS = 20;
const VALID_CLIP_TYPES = ['FORECAST', 'GAME_FORECAST', 'TOTAL', 'TEAM_TOTAL', 'SPREAD', 'SIGNAL_INSIGHT', 'PLAYER_PROP', 'RECOMMENDATION', 'OTHER'];

// GET /api/clipper — user's clips (max 20, newest first)
router.get('/', authMiddleware, async (req: Request, res: Response) => {
  try {
    if (!PANEL_ENABLED()) {
      res.status(400).json({ error: 'Clipper panel is not enabled' });
      return;
    }

    const userId = req.user!.userId;

    const { rows } = await pool.query(
      `SELECT id, clip_type, display_text, forecast_asset_id, event_id, entity_id, note, clipped_at, clip_data
       FROM rm_user_clips
       WHERE user_id = $1
       ORDER BY clipped_at DESC
       LIMIT $2`,
      [userId, MAX_CLIPS]
    );

    res.json({ clips: rows, count: rows.length });
  } catch (err) {
    console.error('Clipper GET error:', err);
    res.status(500).json({ error: 'Failed to fetch clips' });
  }
});

// POST /api/clipper — add a clip (requires CLIPPING_ACTIONS flag)
router.post('/', authMiddleware, async (req: Request, res: Response) => {
  try {
    if (!PANEL_ENABLED()) {
      res.status(400).json({ error: 'Clipper panel is not enabled' });
      return;
    }
    if (!ACTIONS_ENABLED()) {
      res.status(400).json({ error: 'Clipping actions are not currently enabled' });
      return;
    }

    const userId = req.user!.userId;
    const { clip_type, display_text, forecast_asset_id, event_id, entity_id, run_date, clip_data } = req.body || {};

    if (!clip_type || !VALID_CLIP_TYPES.includes(clip_type)) {
      res.status(400).json({ error: `Invalid clip_type. Must be one of: ${VALID_CLIP_TYPES.join(', ')}` });
      return;
    }
    if (!display_text || typeof display_text !== 'string' || display_text.trim().length === 0) {
      res.status(400).json({ error: 'display_text is required' });
      return;
    }

    // Enforce RM forecasted value for clip types that require projections
    const REQUIRES_FORECAST = new Set(['SPREAD', 'TOTAL', 'TEAM_TOTAL', 'PLAYER_PROP']);
    if (REQUIRES_FORECAST.has(clip_type) && clip_data) {
      const fv = clip_data.forecasted_value;
      if (fv == null) {
        console.warn(`Clip rejected: ${clip_type} missing forecasted_value`, { entity_id, clip_type, user_id: userId });
        res.status(400).json({ error: 'RM forecasted value is required for this clip type' });
        return;
      }
    }

    // Check for duplicate via entity_id
    if (entity_id) {
      const { rows: dupeRows } = await pool.query(
        'SELECT id FROM rm_user_clips WHERE user_id = $1 AND entity_id = $2',
        [userId, entity_id]
      );
      if (dupeRows.length > 0) {
        res.status(409).json({ error: 'Already clipped', status: 'duplicate' });
        return;
      }
    }

    // Enforce max 20 clips
    const { rows: countRows } = await pool.query(
      'SELECT COUNT(*)::int AS cnt FROM rm_user_clips WHERE user_id = $1',
      [userId]
    );
    if (countRows[0].cnt >= MAX_CLIPS) {
      res.status(409).json({ error: 'Clip Notepad is full (20). Remove an item to add another.', status: 'full' });
      return;
    }

    const { rows } = await pool.query(
      `INSERT INTO rm_user_clips (user_id, clip_type, display_text, forecast_asset_id, event_id, entity_id, run_date, clip_data)
       VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
       RETURNING id, clip_type, display_text, forecast_asset_id, event_id, entity_id, clipped_at, clip_data`,
      [userId, clip_type, display_text.trim(), forecast_asset_id || null, event_id || null, entity_id || null, run_date || null, clip_data ? JSON.stringify(clip_data) : null]
    );

    res.json({ clip: rows[0], status: 'success' });
  } catch (err: any) {
    if (err.code === '23505') {
      res.status(409).json({ error: 'This item is already clipped' });
      return;
    }
    console.error('Clipper POST error:', err);
    res.status(500).json({ error: 'Failed to add clip' });
  }
});

// DELETE /api/clipper/:clipId — remove one clip
router.delete('/:clipId', authMiddleware, async (req: Request, res: Response) => {
  try {
    if (!PANEL_ENABLED()) {
      res.status(400).json({ error: 'Clipper panel is not enabled' });
      return;
    }

    const userId = req.user!.userId;
    const { clipId } = req.params;

    const { rowCount } = await pool.query(
      'DELETE FROM rm_user_clips WHERE id = $1 AND user_id = $2',
      [clipId, userId]
    );

    if (rowCount === 0) {
      res.status(404).json({ error: 'Clip not found' });
      return;
    }

    res.json({ removed: true, clipId });
  } catch (err) {
    console.error('Clipper DELETE error:', err);
    res.status(500).json({ error: 'Failed to remove clip' });
  }
});

// DELETE /api/clipper?all=true — clear all clips for user
router.delete('/', authMiddleware, async (req: Request, res: Response) => {
  try {
    if (!PANEL_ENABLED()) {
      res.status(400).json({ error: 'Clipper panel is not enabled' });
      return;
    }

    if (req.query.all !== 'true') {
      res.status(400).json({ error: 'Use ?all=true to clear all clips' });
      return;
    }

    const userId = req.user!.userId;

    const { rowCount } = await pool.query(
      'DELETE FROM rm_user_clips WHERE user_id = $1',
      [userId]
    );

    res.json({ cleared: true, removed: rowCount });
  } catch (err) {
    console.error('Clipper CLEAR error:', err);
    res.status(500).json({ error: 'Failed to clear clips' });
  }
});

// POST /api/clipper/email — email user their clip list
router.post('/email', authMiddleware, async (req: Request, res: Response) => {
  try {
    if (!PANEL_ENABLED()) {
      res.status(400).json({ error: 'Clipper panel is not enabled' });
      return;
    }

    const userId = req.user!.userId;

    // Get user email
    const { rows: userRows } = await pool.query(
      'SELECT email FROM rm_users WHERE id = $1',
      [userId]
    );
    if (userRows.length === 0) {
      res.status(404).json({ error: 'User not found' });
      return;
    }
    const email = userRows[0].email;

    // Get clips
    const { rows: clips } = await pool.query(
      `SELECT clip_type, display_text, clipped_at, clip_data
       FROM rm_user_clips
       WHERE user_id = $1
       ORDER BY clipped_at DESC
       LIMIT $2`,
      [userId, MAX_CLIPS]
    );

    if (clips.length === 0) {
      res.status(400).json({ error: 'No clips to email' });
      return;
    }

    await sendClipperEmail(email, clips);

    res.json({ sent: true, to: email, count: clips.length });
  } catch (err) {
    console.error('Clipper EMAIL error:', err);
    res.status(500).json({ error: 'Failed to send email' });
  }
});

export default router;
