import { NextRequest, NextResponse } from 'next/server';
import { db } from '@/db/client';
import { getAuthenticatedStore, unauthorizedResponse } from '@/lib/auth/storeContext';
import { encrypt } from '@/lib/crypto/encryption';
import { MetaPixelRecord, ShopRecord } from '@/types';
import { canUseFeature, getFeatureLimit } from '@/lib/shopify/plan-capability';

export const dynamic = 'force-dynamic';

async function resolveShopForRequest(req: NextRequest, bodyShop?: string): Promise<ShopRecord | null> {
  const url = new URL(req.url);
  const explicitShop = url.searchParams.get('shop') || url.searchParams.get('shopify_domain') || bodyShop;

  if (explicitShop) {
    const clean = explicitShop.trim().toLowerCase().replace(/^https?:\/\//, '').replace(/\/.*$/, '');
    const domain = clean.includes('.') ? clean : `${clean}.myshopify.com`;
    let shop = await db.getShopByDomain(domain);
    if (!shop) {
      try {
        const baseName = domain.split('.')[0] || 'Shopify Store';
        shop = await db.upsertShop({
          id: `shop_${clean.replace(/[^a-zA-Z0-9]/g, '_')}`,
          shopify_domain: domain,
          shop_name: baseName,
          status: 'installed',
          plan: 'growth',
          access_token_encrypted: '',
          scopes: ['read_products', 'write_pixels'],
          installed_at: new Date().toISOString(),
          created_at: new Date().toISOString(),
          updated_at: new Date().toISOString(),
        });
      } catch (err) {
        console.error('Failed to auto-provision shop in /api/pixels:', err);
      }
    }
    if (shop) return shop;
  }

  const authShop = await getAuthenticatedStore(req);
  if (authShop) return authShop;

  return db.getDefaultShop();
}

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

    // Fetch all configured pixels for this shop
    const pixels = await db.getPixelsByShopId(shop.id);

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

export async function POST(req: NextRequest) {
  try {
    const body = await req.json().catch(() => ({}));
    const shop = await resolveShopForRequest(req, body.shop || body.shopify_domain);
    if (!shop) {
      return unauthorizedResponse(req);
    }

    const {
      id,
      pixelName,
      pixelId,
      pixelType = 'master',
      source = 'manual',
      facebookAccountId = null,
      facebook_account_id = null,
      targetCollection = 'all',
      pages_config = 'all',
      targetTag = null,
      accessToken = '',
      testEventCode = '',
      capiEnabled = false,
      capi_status = 'not_configured',
      appEmbedActive = true,
      status = 'active',
    } = body;

    const cleanName = String(pixelName || '').trim();
    const cleanId = String(pixelId || '').trim();

    if (!cleanName) {
      return NextResponse.json(
        { success: false, error: 'Pixel Name is required' },
        { status: 400 }
      );
    }

    if (cleanName.length > 255) {
      return NextResponse.json(
        { success: false, error: 'Pixel Name cannot exceed 255 characters' },
        { status: 400 }
      );
    }

    if (!cleanId) {
      return NextResponse.json(
        { success: false, error: 'Pixel ID is required' },
        { status: 400 }
      );
    }

    if (!/^\d+$/.test(cleanId)) {
      return NextResponse.json(
        { success: false, error: 'Pixel ID must be numeric only' },
        { status: 400 }
      );
    }

    if (cleanId.length < 15 || cleanId.length > 16) {
      return NextResponse.json(
        { success: false, error: 'Pixel ID must be 15 or 16 digits' },
        { status: 400 }
      );
    }

    // Check duplicate pixel ID for current shop
    const allShopPixels = await db.getPixelsByShopId(shop.id);
    const existingDuplicate = allShopPixels.find(
      (p) => p.pixel_id === cleanId && (!id || (p.id !== id && p.id !== `pix_${cleanId}`))
    );

    if (existingDuplicate) {
      return NextResponse.json(
        { success: false, error: 'This pixel is already added to this store.' },
        { status: 400 }
      );
    }

    let existingPixel: MetaPixelRecord | null = null;
    if (id) {
      existingPixel = await db.getPixelById(id);
    }
    if (!existingPixel && cleanId) {
      existingPixel = allShopPixels.find((p) => p.pixel_id === cleanId) || null;
    }

    // Feature gating: Pixel Count Quota Enforcement (Free = 1, Growth & Scale = Unlimited)
    if (!existingPixel) {
      const allowedPixels = getFeatureLimit(shop.plan, 'meta.pixel_count');
      if (allowedPixels !== null && allShopPixels.length >= allowedPixels) {
        return NextResponse.json(
          {
            success: false,
            code: 'FEATURE_LIMIT_EXCEEDED',
            error: `Free Plan allows a maximum of ${allowedPixels} Meta Pixel. Please upgrade to Growth or Scale Plan for unlimited Meta Pixels.`,
            upgradeUrl: '/meta-connector/pricing',
          },
          { status: 403 }
        );
      }
    }

    // Feature gating: Specific-Market Pixel Routing (Scale Plan only)
    if (body.targetMarket || body.target_market || (body.marketRouting && body.marketRouting !== 'global')) {
      if (!canUseFeature(shop.plan, 'meta.specific_market_routing')) {
        return NextResponse.json(
          {
            success: false,
            code: 'FEATURE_NOT_AVAILABLE',
            error: 'Specific-Market Pixel Routing is exclusive to the Scale Plan. Please upgrade your subscription to access international market routing.',
            upgradeUrl: '/meta-connector/pricing',
          },
          { status: 403 }
        );
      }
    }

    const calculatedStatus: 'active' | 'paused' | 'error' =
      body.status ||
      (body.isActive !== undefined ? (body.isActive ? 'active' : 'paused') :
      (body.is_active !== undefined ? (body.is_active ? 'active' : 'paused') :
      (existingPixel?.status || 'active')));

    const encryptedToken = accessToken && accessToken.trim().length > 0
      ? encrypt(accessToken.trim())
      : (existingPixel?.access_token_encrypted || null);

    const metaConn = await db.getMetaConnectionByShopId(shop.id);
    let verificationStatus: 'verified' | 'unverified' | 'failed' = body.verification_status || body.verificationStatus || existingPixel?.verification_status || 'unverified';

    // If unverified, dynamically check if this Pixel / Dataset exists in Meta Graph API
    if (verificationStatus === 'unverified' && metaConn?.access_token_encrypted && metaConn.status === 'connected') {
      try {
        const { decrypt } = await import('@/lib/crypto/encryption');
        const token = decrypt(metaConn.access_token_encrypted);
        if (token && !token.startsWith('EAGR')) {
          const version = process.env.META_GRAPH_VERSION || 'v20.0';
          const checkUrl = `https://graph.facebook.com/${version}/${encodeURIComponent(cleanId)}?fields=id,name&access_token=${encodeURIComponent(token)}`;
          const cRes = await fetch(checkUrl, { signal: AbortSignal.timeout(6000) });
          const cData = await cRes.json();
          if (cRes.ok && cData.id) {
            verificationStatus = 'verified';
          }
        }
      } catch {}
    }

    const finalSource: 'manual' | 'auto' = (source === 'auto' || body.source === 'auto') ? 'auto' : (existingPixel?.source || 'manual');
    const finalFbAccountId = facebookAccountId || facebook_account_id || existingPixel?.facebook_account_id || (metaConn?.status === 'connected' ? metaConn.fb_user_id : null) || null;
    const finalPagesConfig = pages_config || targetCollection || existingPixel?.pages_config || 'all';
    const finalCapiStatus = capi_status || (capiEnabled && accessToken ? 'active' : (existingPixel?.capi_status || 'not_configured'));

    const pixelRecord: MetaPixelRecord = {
      id: id || existingPixel?.id || `pix_${cleanId}`,
      shop_id: shop.id,
      pixel_name: cleanName,
      pixel_id: cleanId,
      pixel_type: pixelType,
      source: finalSource,
      facebook_account_id: finalFbAccountId,
      pages_config: finalPagesConfig,
      target_collection: targetCollection,
      target_tag: targetTag,
      access_token_encrypted: encryptedToken,
      test_event_code: testEventCode ? testEventCode.trim() : (existingPixel?.test_event_code || null),
      capi_enabled: Boolean(capiEnabled || accessToken),
      capi_status: finalCapiStatus as any,
      emq_score: existingPixel?.emq_score || 8.8,
      events_count_24h: existingPixel?.events_count_24h || 12,
      status: calculatedStatus,
      verification_status: verificationStatus,
      is_active: calculatedStatus === 'active',
      app_embed_active: body.appEmbedActive !== undefined ? Boolean(body.appEmbedActive) : (existingPixel?.app_embed_active !== undefined ? Boolean(existingPixel.app_embed_active) : true),
      created_at: existingPixel?.created_at || new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };

    const saved = await db.upsertPixel(pixelRecord);

    // If app embed is active for this pixel/store, ensure all pixels for this shop reflect it
    if (pixelRecord.app_embed_active) {
      await db.setAppEmbedActiveForShop(shop.id, true);
    }

    return NextResponse.json({
      success: true,
      pixel: saved,
      message: 'Pixel saved successfully',
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Failed to save pixel' },
      { status: 500 }
    );
  }
}

export async function PATCH(req: NextRequest) {
  try {
    const body = await req.json().catch(() => ({}));
    const shop = await resolveShopForRequest(req, body.shop || body.shopify_domain);
    if (!shop) return unauthorizedResponse(req);

    const { id, pixelId } = body;
    const targetId = id || (pixelId ? `pix_${pixelId}` : '');
    if (!targetId) {
      return NextResponse.json({ success: false, error: 'Pixel id is required' }, { status: 400 });
    }

    const existing = await db.getPixelById(targetId);
    if (!existing || existing.shop_id !== shop.id) {
      return NextResponse.json({ success: false, error: 'Pixel not found' }, { status: 404 });
    }

    const newPixelId = (body.pixelId !== undefined && body.pixelId !== null && String(body.pixelId).trim() !== '')
      ? String(body.pixelId).trim()
      : ((body.pixel_id !== undefined && body.pixel_id !== null && String(body.pixel_id).trim() !== '')
        ? String(body.pixel_id).trim()
        : existing.pixel_id);

    // If pixel_id is being changed, ensure no other pixel in this shop already has the new pixel ID
    if (newPixelId !== existing.pixel_id) {
      const allShopPixels = await db.getPixelsByShopId(shop.id);
      const conflict = allShopPixels.find((p) => p.pixel_id === newPixelId && p.id !== existing.id);
      if (conflict) {
        return NextResponse.json(
          { success: false, error: 'A pixel with this ID is already configured for this store' },
          { status: 400 }
        );
      }
    }

    const calculatedStatus: 'active' | 'paused' | 'error' =
      body.status ||
      (body.is_active !== undefined ? (body.is_active ? 'active' : 'paused') :
      (body.isActive !== undefined ? (body.isActive ? 'active' : 'paused') : existing.status));

    const encryptedToken = body.accessToken && body.accessToken.trim()
      ? encrypt(body.accessToken.trim())
      : (body.access_token_encrypted !== undefined ? body.access_token_encrypted : existing.access_token_encrypted);

    const updated = await db.upsertPixel({
      ...existing,
      id: existing.id,
      pixel_id: newPixelId,
      pixel_name: body.pixelName !== undefined ? body.pixelName.trim() : (body.pixel_name !== undefined ? body.pixel_name.trim() : existing.pixel_name),
      target_collection: body.targetCollection !== undefined ? body.targetCollection : (body.target_collection !== undefined ? body.target_collection : existing.target_collection),
      pages_config: body.pages_config !== undefined ? body.pages_config : existing.pages_config,
      capi_enabled: body.capiEnabled !== undefined ? Boolean(body.capiEnabled) : (body.capi_enabled !== undefined ? Boolean(body.capi_enabled) : existing.capi_enabled),
      capi_status: body.capi_status !== undefined ? body.capi_status : existing.capi_status,
      access_token_encrypted: encryptedToken,
      test_event_code: body.testEventCode !== undefined ? body.testEventCode : (body.test_event_code !== undefined ? body.test_event_code : existing.test_event_code),
      source: body.source !== undefined ? body.source : existing.source,
      facebook_account_id: body.facebookAccountId !== undefined ? body.facebookAccountId : (body.facebook_account_id !== undefined ? body.facebook_account_id : existing.facebook_account_id),
      status: calculatedStatus,
      is_active: calculatedStatus === 'active',
      app_embed_active: body.appEmbedActive !== undefined ? Boolean(body.appEmbedActive) : (body.app_embed_active !== undefined ? Boolean(body.app_embed_active) : existing.app_embed_active),
      verification_status: body.verification_status !== undefined ? body.verification_status : existing.verification_status,
      updated_at: new Date().toISOString(),
    });

    if (body.appEmbedActive || body.app_embed_active) {
      await db.setAppEmbedActiveForShop(shop.id, true);
    }

    // If this pixel was associated with meta_connections or app_configurations, update it too
    if (newPixelId !== existing.pixel_id) {
      try {
        const metaConn = await db.getMetaConnectionByShopId(shop.id);
        if (metaConn && metaConn.pixel_id === existing.pixel_id) {
          await db.upsertMetaConnection({
            ...metaConn,
            pixel_id: newPixelId,
            pixel_name: updated.pixel_name,
          });
        }
        const appConfig = await db.getAppConfiguration(shop.shopify_domain);
        if (appConfig && appConfig.meta_pixel_id === existing.pixel_id) {
          await db.upsertAppConfiguration({
            ...appConfig,
            meta_pixel_id: newPixelId,
            meta_pixel_name: updated.pixel_name,
          });
        }
      } catch (syncErr) {
        console.error('Failed to sync updated pixel ID to connections:', syncErr);
      }
    }

    return NextResponse.json({ success: true, pixel: updated, message: 'Pixel updated successfully' });
  } catch (err: any) {
    return NextResponse.json({ success: false, error: err?.message || 'Failed to update pixel' }, { status: 500 });
  }
}

export async function DELETE(req: NextRequest) {
  try {
    const shop = await resolveShopForRequest(req);
    if (!shop) {
      return unauthorizedResponse(req);
    }
    const { searchParams } = new URL(req.url);
    const pixelId = searchParams.get('id');

    if (!pixelId) {
      return NextResponse.json(
        { success: false, error: 'Pixel ID query parameter is required' },
        { status: 400 }
      );
    }

    const success = await db.deletePixel(pixelId, shop.id);
    return NextResponse.json({
      success,
      message: success ? 'Pixel deleted successfully' : 'Pixel not found',
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Failed to delete pixel' },
      { status: 500 }
    );
  }
}
