import { Router, Request } from 'express';
import { verifyToken } from '../middleware/auth';
import { createLogger } from '../utils/logger';
import { SupportTicketModel } from '../models/SupportTicket';
import { sendSupportTicketEmail } from '../utils/email';
import { config } from '../config';

const router = Router();
const logger = createLogger('SupportRoutes');

/** Verify a Cloudflare Turnstile token server-side. Returns true on success. */
async function verifyTurnstileToken(token: string, remoteIp: string): Promise<boolean> {
  if (!config.turnstile.secretKey) {
    logger.warn('TURNSTILE_SECRET not configured — skipping Turnstile verification');
    return true; // allow in dev when secret is absent
  }

  if (typeof token !== 'string' || token.length === 0 || token.length > 2048) {
    return false;
  }

  try {
    const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      signal: AbortSignal.timeout(10_000),
      body: new URLSearchParams({
        secret: config.turnstile.secretKey,
        response: token,
        remoteip: remoteIp,
      }),
    });

    if (!res.ok) {
      logger.warn('Turnstile siteverify returned non-OK status', { status: res.status });
      return false;
    }

    const result = await res.json() as { success: boolean; action?: string; hostname?: string };
    if (!result.success) {
      logger.warn('Turnstile verification failed', { result });
      return false;
    }

    // Enforce the action we set on the widget
    if (result.action && result.action !== 'support-ticket') {
      logger.warn('Turnstile action mismatch', { action: result.action });
      return false;
    }

    return true;
  } catch (err) {
    logger.error('Turnstile siteverify request failed', {
      error: err instanceof Error ? err.message : String(err),
    });
    return false;
  }
}

/**
 * POST /support/ticket
 * Submit a new support ticket (authenticated)
 */
router.post('/ticket', verifyToken, async (req: Request, res) => {
  try {
    const { category, subject, message, turnstileToken } = req.body;
    const user = (req as any).user;

    if (!category || !subject || !message) {
      res.status(400).json({ error: 'category, subject, and message are required' });
      return;
    }

    if (subject.trim().length < 3) {
      res.status(400).json({ error: 'Subject must be at least 3 characters' });
      return;
    }

    if (message.trim().length < 10) {
      res.status(400).json({ error: 'Message must be at least 10 characters' });
      return;
    }

    const remoteIp = (req.headers['x-forwarded-for'] as string | undefined)?.split(',')[0]?.trim()
      ?? req.socket.remoteAddress
      ?? '';

    const turnstileOk = await verifyTurnstileToken(String(turnstileToken ?? ''), remoteIp);
    if (!turnstileOk) {
      res.status(403).json({ error: 'Verification failed. Please try again.' });
      return;
    }

    const ticketId = `TKT-${Date.now()}-${Math.random().toString(36).slice(2, 7).toUpperCase()}`;

    await SupportTicketModel.create({
      ticketId,
      userId: user.userId,
      email: user.email,
      category: category.trim(),
      subject: subject.trim(),
      message: message.trim(),
      status: 'open',
    });

    logger.info('Support ticket created', { ticketId, userId: user.userId, category: category.trim() });

    // Send confirmation + inbox notification via Mailjet (fire and forget — don't block the response)
    sendSupportTicketEmail({
      ticketId,
      userEmail: user.email,
      category: category.trim(),
      subject: subject.trim(),
      message: message.trim(),
    }).catch(err =>
      logger.error('Support ticket email failed (non-fatal)', {
        ticketId,
        error: err instanceof Error ? err.message : String(err),
      })
    );

    res.status(201).json({ ticketId, message: 'Ticket submitted successfully' });
  } catch (error) {
    logger.error('Failed to create support ticket', {
      error: error instanceof Error ? error.message : String(error),
    });
    res.status(500).json({ error: 'Failed to submit ticket' });
  }
});

/**
 * GET /support/tickets
 * Get the current user's tickets (authenticated)
 */
router.get('/tickets', verifyToken, async (req, res) => {
  try {
    const user = (req as any).user;
    const tickets = await SupportTicketModel.find({ userId: user.userId }).sort({ createdAt: -1 }).lean();
    res.json({ tickets });
  } catch (error) {
    logger.error('Failed to fetch tickets', {
      error: error instanceof Error ? error.message : String(error),
    });
    res.status(500).json({ error: 'Failed to fetch tickets' });
  }
});

export default router;
