/**
 * Admin API for individual affiliate details
 * Provides detailed stats, conversion history, and referred users
 */

import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import jwt from 'jsonwebtoken';
import { DatabaseService } from '@/lib/database';

// Verify admin access
async function verifyAdmin(): Promise<boolean> {
  const cookieStore = await cookies();
  const authToken = cookieStore.get('auth-token')?.value;

  if (!authToken) return false;

  try {
    const jwtSecret = process.env.JWT_SECRET;
    if (!jwtSecret) return false;

    const decoded = jwt.verify(authToken, jwtSecret) as { userId: string };
    const user = await DatabaseService.findUserById(decoded.userId);

    return user?.role === 'ADMIN' && user?.emailVerified === true;
  } catch {
    return false;
  }
}

// GET - Get detailed affiliate information
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  if (!(await verifyAdmin())) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  const { id } = await params;

  try {
    const mysql = require('mysql2/promise');

    const connection = await mysql.createConnection({
      host: process.env.LEADGEN_DB_HOST || 'localhost',
      user: process.env.LEADGEN_DB_USER || 'leadgen_user',
      password: process.env.LEADGEN_DB_PASS || process.env.LEADGEN_DB_PASSWORD,
      database: process.env.LEADGEN_DB_NAME || 'leadgen',
    });

    try {
      // Get affiliate basic info
      const [affiliateRows] = await connection.execute(
        `SELECT id, company_name, email, unique_id as affiliate_code, status,
                created_at, updated_at
         FROM affiliates WHERE id = ?`,
        [id]
      );

      if (!affiliateRows || affiliateRows.length === 0) {
        return NextResponse.json({ error: 'Affiliate not found' }, { status: 404 });
      }

      const affiliate = affiliateRows[0];

      // Get overall stats
      const [statsRows] = await connection.execute(
        `SELECT
           COUNT(CASE WHEN event_type = 'click' THEN 1 END) as total_clicks,
           COUNT(CASE WHEN event_type = 'signup' THEN 1 END) as total_signups,
           COUNT(CASE WHEN event_type = 'subscription' THEN 1 END) as total_subscriptions,
           COUNT(CASE WHEN event_type = 'purchase' THEN 1 END) as total_purchases,
           COALESCE(SUM(revenue), 0) as total_revenue
         FROM tracking_events WHERE affiliate_id = ?`,
        [id]
      );

      const stats = statsRows[0];

      // Get daily stats for last 30 days
      const [dailyStats] = await connection.execute(
        `SELECT
           DATE(created_at) as date,
           COUNT(CASE WHEN event_type = 'click' THEN 1 END) as clicks,
           COUNT(CASE WHEN event_type = 'signup' THEN 1 END) as signups,
           COUNT(CASE WHEN event_type IN ('subscription', 'purchase') THEN 1 END) as conversions,
           COALESCE(SUM(revenue), 0) as revenue
         FROM tracking_events
         WHERE affiliate_id = ? AND created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
         GROUP BY DATE(created_at)
         ORDER BY date DESC`,
        [id]
      );

      // Get referred users (from the main eventheodds database)
      let referredUsers = [];
      try {
        const prisma = (await import('@prisma/client')).PrismaClient;
        const db = new prisma();
        referredUsers = await db.user.findMany({
          where: {
            affiliateTrackingId: String(id),
          },
          select: {
            id: true,
            email: true,
            firstName: true,
            lastName: true,
            subscriptionTier: true,
            isActive: true,
            createdAt: true,
            _count: {
              select: {
                strategies: true,
              },
            },
          },
          orderBy: { createdAt: 'desc' },
          take: 50,
        });
        await db.$disconnect();
      } catch (e) {
        console.error('Failed to fetch referred users:', e);
      }

      // Get recent events
      const [recentEvents] = await connection.execute(
        `SELECT event_type, referral_source, revenue, created_at
         FROM tracking_events
         WHERE affiliate_id = ?
         ORDER BY created_at DESC
         LIMIT 100`,
        [id]
      );

      // Get conversion breakdown by referral source
      const [sourceBreakdown] = await connection.execute(
        `SELECT
           COALESCE(referral_source, 'direct') as source,
           COUNT(*) as total_events,
           COUNT(CASE WHEN event_type = 'click' THEN 1 END) as clicks,
           COUNT(CASE WHEN event_type IN ('signup', 'subscription', 'purchase') THEN 1 END) as conversions
         FROM tracking_events
         WHERE affiliate_id = ?
         GROUP BY referral_source
         ORDER BY total_events DESC
         LIMIT 20`,
        [id]
      );

      // Get monthly summary
      const [monthlySummary] = await connection.execute(
        `SELECT
           DATE_FORMAT(created_at, '%Y-%m') as month,
           COUNT(CASE WHEN event_type = 'click' THEN 1 END) as clicks,
           COUNT(CASE WHEN event_type IN ('signup', 'subscription', 'purchase') THEN 1 END) as conversions,
           COALESCE(SUM(revenue), 0) as revenue
         FROM tracking_events
         WHERE affiliate_id = ?
         GROUP BY DATE_FORMAT(created_at, '%Y-%m')
         ORDER BY month DESC
         LIMIT 12`,
        [id]
      );

      return NextResponse.json({
        success: true,
        affiliate,
        stats: {
          totalClicks: stats.total_clicks || 0,
          totalSignups: stats.total_signups || 0,
          totalSubscriptions: stats.total_subscriptions || 0,
          totalPurchases: stats.total_purchases || 0,
          totalRevenue: parseFloat(stats.total_revenue) || 0,
          conversionRate: stats.total_clicks > 0
            ? (((stats.total_signups || 0) + (stats.total_subscriptions || 0) + (stats.total_purchases || 0)) / stats.total_clicks * 100).toFixed(2)
            : 0,
        },
        dailyStats,
        referredUsers: referredUsers.map((u: any) => ({
          ...u,
          strategyCount: u._count?.strategies || 0,
        })),
        recentEvents,
        sourceBreakdown,
        monthlySummary,
      });
    } finally {
      await connection.end();
    }
  } catch (error: any) {
    console.error('Failed to fetch affiliate details:', error);
    return NextResponse.json({ error: error.message || 'Internal error' }, { status: 500 });
  }
}

// PUT - Update affiliate information
export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  if (!(await verifyAdmin())) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  const { id } = await params;
  const body = await request.json();

  try {
    const mysql = require('mysql2/promise');

    const connection = await mysql.createConnection({
      host: process.env.LEADGEN_DB_HOST || 'localhost',
      user: process.env.LEADGEN_DB_USER || 'leadgen_user',
      password: process.env.LEADGEN_DB_PASS || process.env.LEADGEN_DB_PASSWORD,
      database: process.env.LEADGEN_DB_NAME || 'leadgen',
    });

    try {
      const updateFields: string[] = [];
      const updateValues: any[] = [];

      const allowedFields = ['status', 'commission_rate', 'notes', 'payment_method', 'payment_details'];

      for (const field of allowedFields) {
        if (body[field] !== undefined) {
          updateFields.push(`${field} = ?`);
          updateValues.push(body[field]);
        }
      }

      if (updateFields.length === 0) {
        return NextResponse.json({ error: 'No valid fields to update' }, { status: 400 });
      }

      updateValues.push(id);

      await connection.execute(
        `UPDATE affiliates SET ${updateFields.join(', ')}, updated_at = NOW() WHERE id = ?`,
        updateValues
      );

      return NextResponse.json({ success: true, message: 'Affiliate updated successfully' });
    } finally {
      await connection.end();
    }
  } catch (error: any) {
    console.error('Failed to update affiliate:', error);
    return NextResponse.json({ error: error.message || 'Internal error' }, { status: 500 });
  }
}
