import { NextRequest, NextResponse } from 'next/server';
import { env } from '@/lib/config/env';
import { logger } from '@/lib/logger';

export const dynamic = 'force-dynamic';

export async function POST(req: NextRequest) {
  try {
    const body = await req.json();
    const rawToken = String(body.accessToken || '').trim();
    const pixelId = String(body.pixelId || '').trim();
    const isAutoConnected = Boolean(body.isAutoConnected || body.source === 'auto');

    if (!rawToken) {
      return NextResponse.json({
        success: true,
        valid: false,
        error: 'Access token cannot be empty',
        message: 'Please paste or enter your Facebook access token.',
      });
    }

    // Minimum sanity check for token format
    if (rawToken.length < 15) {
      return NextResponse.json({
        success: true,
        valid: false,
        error: 'Invalid token format',
        message: 'The token format is invalid (token string is too short). Meta access tokens typically start with EAA.',
      });
    }

    // Explicitly reject Facebook App login tokens (starts with EAGR)
    if (rawToken.startsWith('EAGR')) {
      return NextResponse.json({
        success: true,
        valid: false,
        code: 100,
        error: 'App Login Token Detected',
        message: 'This is a Facebook App login token (starts with EAGR), not a Conversions API Dataset token. Please generate a Conversions API token from Meta Events Manager > Settings > Conversions API > "Set up direct integration" (Set up with Dataset Quality API).',
      });
    }

    const version = env.meta.graphVersion || 'v20.0';

    // 1. Probe 1: If pixelId is provided, verify directly against the Target Dataset (Pixel)
    // Conversions API (CAPI) sends events to /{pixelId}/events, so the token MUST have permission on this Dataset
    if (pixelId) {
      try {
        const pixelUrl = `https://graph.facebook.com/${version}/${encodeURIComponent(pixelId)}?fields=id,name,is_unavailable&access_token=${encodeURIComponent(rawToken)}`;
        const pixelRes = await fetch(pixelUrl, { signal: AbortSignal.timeout(7000), cache: 'no-store' });
        const pixelData = await pixelRes.json();

        if (pixelRes.ok && pixelData.id) {
          // Verify Dataset Quality API capability as requested by user
          let emqScore: number | null = null;
          try {
            const qualityUrl = `https://graph.facebook.com/${version}/dataset_quality?dataset_id=${encodeURIComponent(pixelId)}&fields=web{event_match_quality,event_name}&access_token=${encodeURIComponent(rawToken)}`;
            const qualityRes = await fetch(qualityUrl, { signal: AbortSignal.timeout(5000), cache: 'no-store' });
            const qualityData = await qualityRes.json();
            if (qualityRes.ok && qualityData.web?.[0]?.event_match_quality?.composite_score) {
              emqScore = qualityData.web[0].event_match_quality.composite_score;
            }
          } catch {
            // Supplementary check
          }

          return NextResponse.json({
            success: true,
            valid: true,
            type: 'DATASET_QUALITY_TOKEN',
            dataset: {
              id: pixelData.id,
              name: pixelData.name || pixelId,
              emqScore,
            },
            pixel: {
              id: pixelData.id,
              name: pixelData.name || pixelId,
            },
            user: {
              id: pixelData.id,
              name: pixelData.name || `Dataset ${pixelId}`,
            },
            message: `Token validated successfully with direct access to Meta Dataset "${pixelData.name || pixelId}". Dataset Quality API & Conversions API permissions confirmed.`,
          });
        }

        // Probe 2: Probe Dataset Quality API endpoint directly (/dataset_quality)
        try {
          const qualityUrl = `https://graph.facebook.com/${version}/dataset_quality?dataset_id=${encodeURIComponent(pixelId)}&fields=web{event_match_quality,event_name}&access_token=${encodeURIComponent(rawToken)}`;
          const qualityRes = await fetch(qualityUrl, { signal: AbortSignal.timeout(6000), cache: 'no-store' });
          const qualityData = await qualityRes.json();

          if (qualityRes.ok && (qualityData.web !== undefined || qualityData.data !== undefined)) {
            return NextResponse.json({
              success: true,
              valid: true,
              type: 'DATASET_QUALITY_API',
              dataset: {
                id: pixelId,
                name: `Dataset ${pixelId}`,
              },
              pixel: {
                id: pixelId,
                name: `Dataset ${pixelId}`,
              },
              message: `Token validated successfully via Meta Dataset Quality API for Dataset ${pixelId}.`,
            });
          }
        } catch {
          // Quality probe fallback
        }

        // If Meta returned an explicit error for this dataset
        if (pixelData.error) {
          const errCode = pixelData.error.code;
          const errMsg = pixelData.error.message || 'Invalid access token';

          // Code 190: Malformed, invalid, or expired access token
          if (errCode === 190) {
            return NextResponse.json({
              success: true,
              valid: false,
              code: 190,
              error: 'Malformed or Expired Token',
              message: `Meta Graph API rejected this token (Code 190): ${errMsg}. Please copy a fresh token from Meta Events Manager > Settings > Conversions API > "Set up direct integration".`,
            });
          }

          // Code 100 / 200 / 298: Token exists, but has NO permission on this Pixel / Dataset
          if (errCode === 100 || errCode === 200 || errCode === 298) {
            return NextResponse.json({
              success: true,
              valid: false,
              code: errCode,
              error: 'Dataset Permission Denied',
              message: `This access token does not have permission for Dataset ${pixelId}. Please copy the token from Meta Events Manager > Datasets > Settings > Conversions API > "Set up direct integration" (Set up with Dataset Quality API).`,
            });
          }

          return NextResponse.json({
            success: true,
            valid: false,
            code: errCode,
            error: errMsg,
            message: `Meta Graph API error for Dataset ${pixelId}: ${errMsg}`,
          });
        }
      } catch (err: any) {
        logger.warn('[VerifyToken] Direct dataset probe note:', err.message);
      }
    }

    // If pixelId was provided and both probes failed, DO NOT fall back to generic /me
    if (pixelId) {
      return NextResponse.json({
        success: true,
        valid: false,
        code: 100,
        error: 'Dataset Access Verification Failed',
        message: `Could not verify access to Dataset ${pixelId}. Please ensure you copied the token from Meta Events Manager > Datasets > Settings > Conversions API > "Set up direct integration" (Set up with Dataset Quality API).`,
      });
    }

    // 2. Probe 2: If no pixelId specified, test /me
    try {
      const meUrl = `https://graph.facebook.com/${version}/me?fields=id,name,email&access_token=${encodeURIComponent(rawToken)}`;
      const meRes = await fetch(meUrl, { signal: AbortSignal.timeout(6000), cache: 'no-store' });
      const meData = await meRes.json();

      if (meRes.ok && meData.id) {
        return NextResponse.json({
          success: true,
          valid: true,
          type: 'USER',
          user: {
            id: meData.id,
            name: meData.name || 'Meta User',
            email: meData.email || null,
          },
          message: `Token verified with Meta Graph API (${meData.name || 'Account ID: ' + meData.id}).`,
        });
      }

      if (meData?.error) {
        return NextResponse.json({
          success: true,
          valid: false,
          code: meData.error.code || 190,
          error: meData.error.message || 'Invalid or expired Meta access token',
          message: `Meta Graph API rejected this token: ${meData.error.message || 'Malformed or expired access token'}.`,
        });
      }
    } catch {
      // Continue to debug_token probe
    }

    // 3. Probe 3: Check via debug_token if App ID & Secret are configured
    const appId = env.meta.appId;
    const appSecret = env.meta.appSecret;
    if (appId && appSecret) {
      try {
        const debugUrl = `https://graph.facebook.com/${version}/debug_token?input_token=${encodeURIComponent(rawToken)}&access_token=${encodeURIComponent(appId)}|${encodeURIComponent(appSecret)}`;
        const debugRes = await fetch(debugUrl, { signal: AbortSignal.timeout(6000), cache: 'no-store' });
        const debugData = await debugRes.json();

        if (debugRes.ok && debugData?.data?.is_valid) {
          return NextResponse.json({
            success: true,
            valid: true,
            type: debugData.data.type || 'SYSTEM_USER',
            expiresAt: debugData.data.expires_at || null,
            scopes: debugData.data.scopes || [],
            message: 'Token verified and valid via Meta debug_token inspection.',
          });
        }

        if (debugData?.data?.error?.message) {
          return NextResponse.json({
            success: true,
            valid: false,
            code: debugData.data.error.code || 190,
            error: debugData.data.error.message,
            message: `Meta Graph API rejected this token: ${debugData.data.error.message}`,
          });
        }
      } catch {
        // debug_token failed or timed out
      }
    }

    // If all probes failed, reject the token
    return NextResponse.json({
      success: true,
      valid: false,
      code: 190,
      error: 'Invalid or Malformed Meta Access Token',
      message: 'Meta Graph API rejected this token: Malformed, invalid, or expired access token. Please copy a fresh Conversions API access token from Meta Events Manager.',
    });
  } catch (err) {
    logger.error('[VerifyToken] Unexpected error:', err);
    return NextResponse.json(
      {
        success: false,
        valid: false,
        error: err instanceof Error ? err.message : 'Server error verifying token',
      },
      { status: 500 }
    );
  }
}
