import { NextRequest, NextResponse } from 'next/server';
import { db } from '@/db/client';
import { getAuthenticatedStore, unauthorizedResponse } from '@/lib/auth/storeContext';
import { decrypt } from '@/lib/crypto/encryption';
import { META_CONFIG, buildMetaGraphUrl } from '@/config/meta';

export const dynamic = 'force-dynamic';

export async function GET(req: NextRequest) {
  try {
    const shop = await getAuthenticatedStore(req);
    if (!shop) {
      return unauthorizedResponse();
    }

    const metaConn = await db.getMetaConnectionByShopId(shop.id);
    const shopRecord = await db.getShopById(shop.id);
    const plan = shopRecord?.plan || 'growth';

    // If Meta Account is connected, fetch live campaigns or return active store campaigns
    let campaigns: any[] = [];
    if (metaConn?.access_token_encrypted) {
      try {
        const token = decrypt(metaConn.access_token_encrypted);
        // If real Meta Marketing token is available, we query Meta Graph campaigns
        if (token && !token.startsWith('mock_')) {
          const bizId = metaConn.business_id;
          const graphRes = await fetch(
            buildMetaGraphUrl(`/${bizId}/adaccounts?fields=id,name,campaigns{id,name,status,daily_budget,insights{spend,impressions,clicks,cpc,ctr,actions,action_values}}&access_token=${encodeURIComponent(token)}`)
          );
          const graphData = await graphRes.json();
          if (graphData?.data?.[0]?.campaigns?.data) {
            campaigns = graphData.data[0].campaigns.data.map((c: any) => {
              const ins = c.insights?.data?.[0] || {};
              const spend = parseFloat(ins.spend || '0');
              const revenue = parseFloat(ins.action_values?.find((a: any) => a.action_type === 'omni_purchase')?.value || '0');
              const purchases = parseInt(ins.actions?.find((a: any) => a.action_type === 'omni_purchase')?.value || '0', 10);
              const clicks = parseInt(ins.clicks || '0', 10);
              const impressions = parseInt(ins.impressions || '0', 10);
              const ctr = impressions > 0 ? (clicks / impressions) * 100 : 0;
              const cpc = clicks > 0 ? spend / clicks : 0;
              const roas = spend > 0 ? revenue / spend : 0;
              return {
                id: c.id,
                name: c.name,
                status: c.status === 'ACTIVE' ? 'ACTIVE' : 'PAUSED',
                budget: parseFloat(c.daily_budget || '0') / 100,
                spend,
                impressions,
                clicks,
                ctr: parseFloat(ctr.toFixed(2)),
                cpc: parseFloat(cpc.toFixed(2)),
                purchases,
                revenue,
                roas: parseFloat(roas.toFixed(2)),
              };
            });
          }
        }
      } catch (e) {
        // Fallback to empty if unable to reach Meta Graph
        campaigns = [];
      }
    }

    if (campaigns.length === 0) {
      campaigns = await db.getCampaignsByShopId(shop.id);
    }

    const dbPlan = await db.getPlan(plan);
    const maxCampaigns = dbPlan ? dbPlan.campaigns_limit : (plan === 'accelerate' ? null : plan === 'growth' ? 10 : 1);

    return NextResponse.json({
      success: true,
      shopDomain: shop.shopify_domain,
      plan,
      maxCampaigns,
      campaigns,
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Failed to fetch campaigns' },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    const shop = await getAuthenticatedStore(req);
    if (!shop) {
      return unauthorizedResponse();
    }

    const shopRecord = await db.getShopById(shop.id);
    const plan = shopRecord?.plan || 'basic';
    const dbPlan = await db.getPlan(plan);
    const maxCampaigns = dbPlan ? dbPlan.campaigns_limit : (plan === 'accelerate' ? null : plan === 'growth' ? 10 : 1);

    // Enforce Plan Ad Campaign Limit
    const existingCampaigns = await db.getCampaignsByShopId(shop.id);
    if (maxCampaigns !== null && existingCampaigns.length >= maxCampaigns) {
      return NextResponse.json(
        {
          success: false,
          error: `Your current ${plan === 'basic' ? 'Free' : plan} plan allows a maximum of ${maxCampaigns} Facebook Basic Ad Campaign${maxCampaigns > 1 ? 's' : ''}. Paid plans are currently disabled during launch.`,
          quotaExceeded: true,
          limit: maxCampaigns,
          current: existingCampaigns.length,
        },
        { status: 403 }
      );
    }

    const body = await req.json();
    const { name, budget } = body;

    const newCampaign = {
      id: `cmp_${Date.now()}`,
      shop_id: shop.id,
      name: name || 'Advantage+ Shopping Campaign',
      status: 'ACTIVE',
      budget: parseFloat(budget) || 25.0,
      spend: 0,
      impressions: 0,
      clicks: 0,
      ctr: 0,
      cpc: 0,
      purchases: 0,
      revenue: 0,
      roas: 0,
    };

    await db.createCampaign(newCampaign);

    return NextResponse.json({
      success: true,
      campaign: newCampaign,
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Failed to create campaign' },
      { status: 500 }
    );
  }
}

export async function PATCH(req: NextRequest) {
  try {
    const shop = await getAuthenticatedStore(req);
    if (!shop) {
      return unauthorizedResponse();
    }

    const body = await req.json();
    const { id, status } = body;
    if (!id || !status) {
      return NextResponse.json({ success: false, error: 'id and status are required' }, { status: 400 });
    }

    await db.updateCampaignStatus(id, shop.id, status);

    return NextResponse.json({
      success: true,
      id,
      status,
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Failed to update campaign' },
      { status: 500 }
    );
  }
}
