import { Router, Request, Response } from 'express';
import { query, queryOne } from '../db';
import { logger } from '../logger';
import { TRACKING_PIXEL } from '../services/trackingPixel';

const router = Router();

/** Shared GET/POST handler body for one-click + link unsubscribe. */
async function runUnsubscribe(token: string): Promise<{ ok: true } | { ok: false; reason: string }> {
  const recipient = await queryOne<{ id: string; campaign_id: string; contact_id: string }>(
    'SELECT id, campaign_id, contact_id FROM campaign_recipients WHERE track_token = $1',
    [token]
  );

  if (!recipient) return { ok: false, reason: 'invalid' };

  await query('UPDATE contacts SET subscribed = false, updated_at = now() WHERE id = $1', [recipient.contact_id]);
  await query(
    `INSERT INTO email_events (campaign_id, contact_id, type) VALUES ($1, $2, 'unsubscribed')`,
    [recipient.campaign_id, recipient.contact_id]
  );
  return { ok: true };
}

const unsubHtmlOk = `<!DOCTYPE html>
<html>
<head><title>Unsubscribed</title>
<style>body{font-family:sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f5f5f5}
.box{background:#fff;padding:2rem 3rem;border-radius:8px;text-align:center;box-shadow:0 2px 8px rgba(0,0,0,.1)}
h1{color:#333}p{color:#666}</style></head>
<body><div class="box"><h1>You've been unsubscribed</h1><p>You will no longer receive emails from this list.</p></div></body>
</html>`;

// ─── Open Pixel ──────────────────────────────────────────────────────────────
router.get('/open/:token(*)', async (req: Request, res: Response) => {
  const token = req.params.token.replace(/\.gif$/i, '');

  res.set({
    'Content-Type': 'image/gif',
    'Cache-Control': 'no-cache, no-store, must-revalidate',
    'Pragma': 'no-cache',
    'Expires': '0',
  });
  res.end(TRACKING_PIXEL);

  setImmediate(async () => {
    try {
      const recipient = await queryOne<{ id: string; campaign_id: string; contact_id: string; opened_at: string | null }>(
        'SELECT id, campaign_id, contact_id, opened_at FROM campaign_recipients WHERE track_token = $1',
        [token]
      );
      if (!recipient) return;

      if (!recipient.opened_at) {
        await query(
          'UPDATE campaign_recipients SET opened_at = now() WHERE id = $1',
          [recipient.id]
        );
        await query(
          `INSERT INTO email_events (campaign_id, contact_id, type, metadata) VALUES ($1, $2, 'opened', $3)`,
          [recipient.campaign_id, recipient.contact_id, JSON.stringify({ user_agent: req.headers['user-agent'], ip: req.ip })]
        );
      }
    } catch (err) {
      logger.error(err, 'Tracking pixel error');
    }
  });
});

// ─── Click Redirect ──────────────────────────────────────────────────────────
router.get('/click/:token(*)', async (req: Request, res: Response) => {
  const combined = req.params.token;
  const lastDot = combined.lastIndexOf('.');
  const linkToken = combined.substring(0, lastDot);
  const recipientToken = combined.substring(lastDot + 1);

  const link = await queryOne<{ id: string; campaign_id: string; original_url: string }>(
    'SELECT id, campaign_id, original_url FROM tracked_links WHERE tracking_token = $1',
    [linkToken]
  ).catch(() => null);

  if (!link) {
    return res.status(404).send('Link not found');
  }

  res.redirect(302, link.original_url);

  setImmediate(async () => {
    try {
      const recipient = await queryOne<{ id: string; contact_id: string; clicked_at: string | null }>(
        'SELECT id, contact_id, clicked_at FROM campaign_recipients WHERE track_token = $1',
        [recipientToken]
      );

      if (!recipient) return;

      await query(
        'INSERT INTO tracked_link_clicks (tracked_link_id, recipient_id, user_agent, ip_address) VALUES ($1, $2, $3, $4)',
        [link.id, recipient.id, req.headers['user-agent'] || null, req.ip || null]
      );

      await query('UPDATE tracked_links SET click_count = click_count + 1 WHERE id = $1', [link.id]);

      if (!recipient.clicked_at) {
        await query('UPDATE campaign_recipients SET clicked_at = now() WHERE id = $1', [recipient.id]);
        await query(
          `INSERT INTO email_events (campaign_id, contact_id, type, metadata) VALUES ($1, $2, 'clicked', $3)`,
          [link.campaign_id, recipient.contact_id, JSON.stringify({ url: link.original_url, link_id: link.id })]
        );
      }
    } catch (err) {
      logger.error(err, 'Click tracking error');
    }
  });
});

// ─── Unsubscribe (GET — browser link) ────────────────────────────────────────
router.get('/unsubscribe/:token', async (req: Request, res: Response) => {
  try {
    const result = await runUnsubscribe(req.params.token);
    if (!result.ok) {
      return res.status(404).send('<h1>Invalid unsubscribe link</h1>');
    }
    res.send(unsubHtmlOk);
  } catch (err) {
    logger.error(err, 'Unsubscribe error');
    res.status(500).send('<h1>Something went wrong. Please try again.</h1>');
  }
});

// ─── Unsubscribe (POST — RFC 8058 one-click) ─────────────────────────────────
router.post('/unsubscribe/:token', async (req: Request, res: Response) => {
  try {
    const result = await runUnsubscribe(req.params.token);
    if (!result.ok) {
      return res.status(404).json({ error: 'Invalid unsubscribe token' });
    }
    res.status(204).end();
  } catch (err) {
    logger.error(err, 'Unsubscribe POST error');
    res.status(500).json({ error: 'Unsubscribe failed' });
  }
});

export default router;
