import { NextRequest } from 'next/server'
import nodemailer from 'nodemailer'
import { verifyApproveToken } from '@/lib/token'
import { activateChannels } from '@/lib/threadfin'

function htmlPage(title: string, body: string): Response {
  return new Response(
    `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>${title} — Jefflix</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 60px auto; padding: 0 20px; color: #1a1a1a; background: #0a0a0a; color: #e5e5e5; }
    .card { background: #1a1a1a; border: 1px solid #333; border-radius: 12px; padding: 32px; }
    .icon { font-size: 48px; margin-bottom: 16px; }
    h1 { margin: 0 0 16px; font-size: 24px; }
    ul { padding-left: 20px; line-height: 1.8; }
    code { background: #2a2a2a; padding: 2px 6px; border-radius: 4px; font-size: 13px; }
    .success { color: #4ade80; }
    .warning { color: #facc15; }
    .error { color: #f87171; }
    .muted { color: #888; font-size: 13px; margin-top: 24px; }
  </style>
</head>
<body>
  <div class="card">
    ${body}
  </div>
</body>
</html>`,
    { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' } },
  )
}

export async function GET(request: NextRequest) {
  const token = request.nextUrl.searchParams.get('token')

  if (!token) {
    return htmlPage('Invalid Link', `
      <div class="icon">&#10060;</div>
      <h1 class="error">Invalid Link</h1>
      <p>No approval token provided.</p>
    `)
  }

  const payload = verifyApproveToken(token)
  if (!payload) {
    return htmlPage('Expired or Invalid', `
      <div class="icon">&#9203;</div>
      <h1 class="error">Link Expired or Invalid</h1>
      <p>This approval link has expired or is invalid. Channel requests expire after 7 days.</p>
      <p>Ask the user to submit a new request.</p>
    `)
  }

  try {
    const result = await activateChannels(
      payload.channels.map((ch) => ch.id),
    )

    // Send confirmation email to the requester
    await sendConfirmationEmail(payload.email, result.activated, result.notFound, payload.channels)

    const activatedHtml = result.activated.length > 0
      ? `<h2 class="success">Activated (${result.activated.length})</h2>
         <ul>${result.activated.map((id) => {
           const ch = payload.channels.find((c) => c.id === id)
           return `<li><strong>${ch?.name ?? id}</strong> — <code>${id}</code></li>`
         }).join('')}</ul>`
      : ''

    const notFoundHtml = result.notFound.length > 0
      ? `<h2 class="warning">Not Found in Playlists (${result.notFound.length})</h2>
         <ul>${result.notFound.map((id) => {
           const ch = payload.channels.find((c) => c.id === id)
           return `<li><strong>${ch?.name ?? id}</strong> — <code>${id}</code></li>`
         }).join('')}</ul>
         <p class="muted">These channels aren't in the current M3U playlists (english/news/sports). Add them to Threadfin's playlist sources first.</p>`
      : ''

    return htmlPage('Channels Approved', `
      <div class="icon">&#9989;</div>
      <h1 class="success">Channels Approved</h1>
      <p>Request from <strong>${escapeHtml(payload.email)}</strong> has been processed.</p>
      ${activatedHtml}
      ${notFoundHtml}
      <p class="muted">A confirmation email has been sent to the requester.</p>
    `)
  } catch (err) {
    console.error('Channel activation error:', err)
    return htmlPage('Activation Failed', `
      <div class="icon">&#10060;</div>
      <h1 class="error">Activation Failed</h1>
      <p>Could not connect to Threadfin or activate channels.</p>
      <p><code>${escapeHtml(err instanceof Error ? err.message : String(err))}</code></p>
      <p>Check Threadfin is running and credentials are correct.</p>
    `)
  }
}

async function sendConfirmationEmail(
  to: string,
  activated: string[],
  notFound: string[],
  channels: { id: string; name: string }[],
) {
  const smtpHost = process.env.SMTP_HOST
  const smtpUser = process.env.SMTP_USER
  const smtpPass = process.env.SMTP_PASS
  if (!smtpHost || !smtpUser || !smtpPass) return

  const transporter = nodemailer.createTransport({
    host: smtpHost,
    port: Number(process.env.SMTP_PORT) || 587,
    secure: false,
    auth: { user: smtpUser, pass: smtpPass },
    tls: { rejectUnauthorized: false },
  })

  const activatedList = activated.map((id) => {
    const ch = channels.find((c) => c.id === id)
    return `<li>&#9989; <strong>${escapeHtml(ch?.name ?? id)}</strong></li>`
  }).join('')

  const notFoundList = notFound.map((id) => {
    const ch = channels.find((c) => c.id === id)
    return `<li>&#10060; <strong>${escapeHtml(ch?.name ?? id)}</strong> — not available in current playlists</li>`
  }).join('')

  await transporter.sendMail({
    from: `Jefflix <${smtpUser}>`,
    to,
    subject: `[Jefflix] Your channel request has been processed`,
    html: `
      <h2>Your Channel Request Update</h2>
      ${activated.length > 0 ? `
        <p>The following channels have been activated and should appear in your guide shortly:</p>
        <ul style="line-height: 1.8;">${activatedList}</ul>
      ` : ''}
      ${notFound.length > 0 ? `
        <p>The following channels were not found in the current playlists:</p>
        <ul style="line-height: 1.8;">${notFoundList}</ul>
        <p style="color: #666; font-size: 13px;">These may become available when new playlist sources are added.</p>
      ` : ''}
      ${activated.length > 0 ? '<p>It may take a few minutes for the channels to appear in your TV guide. If you don\'t see them after 15 minutes, try refreshing your IPTV app.</p>' : ''}
      <hr style="margin: 20px 0; border: none; border-top: 1px solid #ddd;" />
      <p style="color: #666; font-size: 12px;">Jefflix · ${new Date().toLocaleString()}</p>
    `,
  })
}

function escapeHtml(text: string): string {
  const map: Record<string, string> = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;',
  }
  return text.replace(/[&<>"']/g, (char) => map[char])
}
