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 { MetaCatalogService } from '@/lib/meta/catalog-service';
import { syncCatalog } from '@/lib/sync/catalog-sync-service';
import { calculateNextSyncDate } from '@/lib/sync/scheduler';
import { CatalogFormData, CatalogRecord, CatalogSelectionRecord } from '@/types/catalog';
import { getFeatureLimit } from '@/lib/shopify/plan-capability';

export const dynamic = 'force-dynamic';

export async function GET(req: NextRequest) {
  try {
    const shopDomain = req.nextUrl.searchParams.get('shop') || req.nextUrl.searchParams.get('shopify_domain');
    let shop = await getAuthenticatedStore(req);
    if (!shop && shopDomain) {
      shop = await db.getShopByDomain(shopDomain);
    }
    if (!shop) {
      return unauthorizedResponse();
    }

    // Check Facebook connection for this store
    const metaConn = await db.getMetaConnectionByShopId(shop.id);
    const isConnected = Boolean(metaConn?.status === 'connected' && metaConn?.access_token_encrypted);
    const activeFbUserId = isConnected ? (metaConn?.fb_user_id || metaConn?.business_id || null) : null;

    // Filter catalogs by currently connected Facebook account
    const catalogs = isConnected ? await db.getCatalogs(shop.id, activeFbUserId) : [];

    // Get current store plan limits
    const plan = shop.plan ? await db.getPlan(shop.plan) : null;
    const catalogLimit = plan ? (plan.campaigns_limit ?? null) : 1;
    const productLimit = plan ? (plan.sku_limit ?? null) : 100;

    // Count store products
    let storeProductCount = 0;
    try {
      const prods = await db.getProductsByShopId(shop.id);
      storeProductCount = prods.length;
    } catch {
      storeProductCount = 0;
    }

    // Calculate trial days remaining if on trial
    let trialDaysRemaining: number | null = null;
    if (shop.trial_ends_at) {
      const diffMs = new Date(shop.trial_ends_at).getTime() - Date.now();
      trialDaysRemaining = Math.max(0, Math.ceil(diffMs / (1000 * 60 * 60 * 24)));
    }

    return NextResponse.json({
      success: true,
      catalogs,
      fbConnected: isConnected,
      stats: {
        totalProducts: storeProductCount,
        productLimit,
        totalCatalogs: catalogs.length,
        catalogLimit,
        planId: shop.plan || 'basic',
        planName: plan?.name || 'Basic Plan',
        subscriptionStatus: shop.subscription_status || (shop.plan === 'basic' ? 'free' : 'active'),
        trialDaysRemaining,
      },
    });
  } catch (err: any) {
    console.error('[API /api/catalogs GET] Error:', err);
    return NextResponse.json(
      { success: false, error: err.message || 'Failed to fetch catalogs' },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    const shopDomain = req.nextUrl.searchParams.get('shop') || req.nextUrl.searchParams.get('shopify_domain');
    let shop = await getAuthenticatedStore(req);
    if (!shop && shopDomain) {
      shop = await db.getShopByDomain(shopDomain);
    }
    if (!shop) {
      return unauthorizedResponse();
    }

    // Server-side Gate: Facebook connection is strictly required
    const metaConn = await db.getMetaConnectionByShopId(shop.id);
    if (!metaConn || metaConn.status !== 'connected' || !metaConn.access_token_encrypted) {
      return NextResponse.json(
        { success: false, error: 'Facebook account not connected' },
        { status: 403 }
      );
    }

    let accessToken = '';
    try {
      accessToken = decrypt(metaConn.access_token_encrypted);
    } catch {
      accessToken = '';
    }

    if (!accessToken) {
      return NextResponse.json(
        { success: false, error: 'Facebook account not connected' },
        { status: 403 }
      );
    }

    const body: CatalogFormData = await req.json();

    // Required fields validation
    const businessId = String(body.business_id || '').trim();
    if (!businessId) {
      return NextResponse.json(
        { success: false, error: 'Facebook Business Account is required' },
        { status: 400 }
      );
    }

    const pixelId = String(body.pixel_id || '').trim();
    if (!pixelId) {
      return NextResponse.json(
        { success: false, error: 'Meta Pixel (External Event Source) is required' },
        { status: 400 }
      );
    }

    const catalogName = String(body.name || '').trim();
    if (!catalogName) {
      return NextResponse.json(
        { success: false, error: 'Catalog name is required' },
        { status: 400 }
      );
    }

    if (catalogName.length > 150) {
      return NextResponse.json(
        { success: false, error: 'Catalog name cannot exceed 150 characters' },
        { status: 400 }
      );
    }

    // Check catalog feed quota based on current store plan (Free = 1, Growth = 3, Scale = Unlimited)
    const activeFbUserId = metaConn.fb_user_id || metaConn.business_id || null;
    const existingCatalogs = await db.getCatalogs(shop.id, activeFbUserId);
    const plan = shop.plan ? await db.getPlan(shop.plan) : null;
    const catalogLimit = getFeatureLimit(shop.plan, 'meta.catalog_feeds') ?? (plan ? plan.campaigns_limit : 1);

    if (catalogLimit !== null && existingCatalogs.length >= catalogLimit) {
      return NextResponse.json(
        {
          success: false,
          code: 'FEATURE_LIMIT_EXCEEDED',
          error: `You have reached the maximum limit of ${catalogLimit} catalog feed(s) for your current plan (${plan?.name || 'Free Plan'}). Please upgrade to Growth (3 feeds) or Scale (Unlimited) to create additional catalog feeds.`,
          requiresUpgrade: true,
          upgradeUrl: '/meta-connector/pricing',
        },
        { status: 403 }
      );
    }

    let fbCatalogId = body.fb_catalog_id ? body.fb_catalog_id.trim() : '';

    // If creating a new catalog, call Meta Graph API under the selected business
    if (!fbCatalogId && businessId && accessToken) {
      try {
        const createRes = await MetaCatalogService.createCatalog(businessId, catalogName, accessToken);
        if (createRes.success && createRes.catalogId) {
          fbCatalogId = createRes.catalogId;
        }
      } catch (e: any) {
        console.warn('[API /api/catalogs POST] Meta Graph API note:', e.message);
      }
    }

    if (!fbCatalogId) {
      fbCatalogId = `${Math.floor(1000000000000000 + Math.random() * 9000000000000000)}`;
    }

    // Link selected pixel as the external event source
    if (pixelId && accessToken && fbCatalogId) {
      try {
        await MetaCatalogService.linkPixel(fbCatalogId, pixelId, accessToken);
      } catch (pxErr: any) {
        console.warn('[API /api/catalogs POST] Meta Graph API linkPixel note:', pxErr.message);
      }
    }

    const catalogId = `cat_${Date.now()}`;
    const nextSyncAt = calculateNextSyncDate(
      body.schedule_type || 'weekly',
      body.schedule_day || 'Every Monday',
      body.schedule_hour || 2,
      body.schedule_period || 'AM',
      body.schedule_tz || 'UTC'
    );

    const syncRules = {
      sync_scope: body.sync_scope || 'all',
      selected_collections: body.selected_collections || [],
      selected_tags: body.selected_tags || [],
      selected_products: body.selected_products || [],
      exclude_out_of_stock: Boolean(body.exclude_out_of_stock),
      excluded_collections: body.excluded_collections || [],
      excluded_tags: body.excluded_tags || [],
      excluded_products: body.excluded_products || [],
    };

    const newCatalog: CatalogRecord = {
      id: catalogId,
      shop_id: shop.id,
      facebook_account_id: activeFbUserId,
      sync_rules: syncRules,
      fb_catalog_id: fbCatalogId,
      fb_business_id: businessId,
      fb_pixel_id: pixelId,
      name: catalogName,
      sync_scope: body.sync_scope || 'all',
      variant_mode: body.variant_mode || 'all_separate',
      google_category_id: body.google_category_id || '',
      google_category_name: body.google_category_name || '',
      additional_images: body.additional_images !== false,
      link_domain: body.link_domain || 'myshopify',
      custom_domain: body.custom_domain || null,
      exclude_out_of_stock: Boolean(body.exclude_out_of_stock),
      price_mode: body.price_mode || 'compare_at_and_price',
      schedule_type: body.schedule_type || 'weekly',
      schedule_day: body.schedule_day || 'Every Monday',
      schedule_hour: body.schedule_hour || 2,
      schedule_period: body.schedule_period || 'AM',
      schedule_tz: body.schedule_tz || 'UTC',
      auto_sync: body.auto_sync !== false,
      pixel_tracking: true,
      status: 'synced',
      last_synced_at: null,
      next_sync_at: nextSyncAt ? (typeof nextSyncAt === 'string' ? nextSyncAt : (nextSyncAt as any).toISOString()) : null,
      last_error: null,
      fb_catalog_url: MetaCatalogService.getCommerceManagerUrl(fbCatalogId, businessId),
      product_count: 0,
      variant_count: 0,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    };

    await db.createCatalog(newCatalog);

    // Save item selections and exclusions
    const selectionsToInsert: Array<Omit<CatalogSelectionRecord, 'id' | 'catalog_id'>> = [];
    if (body.sync_scope === 'selected') {
      if (Array.isArray(body.selected_collections)) {
        for (const col of body.selected_collections) {
          selectionsToInsert.push({ type: 'collection', shopify_gid: col.id, value: col.title, is_exclude: false });
        }
      }
      if (Array.isArray(body.selected_tags)) {
        for (const tag of body.selected_tags) {
          selectionsToInsert.push({ type: 'tag', shopify_gid: tag, value: tag, is_exclude: false });
        }
      }
      if (Array.isArray(body.selected_products)) {
        for (const prod of body.selected_products) {
          selectionsToInsert.push({ type: 'product', shopify_gid: prod.id, value: prod.title, is_exclude: false });
        }
      }
    }

    if (Array.isArray(body.excluded_collections)) {
      for (const col of body.excluded_collections) {
        selectionsToInsert.push({ type: 'collection', shopify_gid: col.id, value: col.title, is_exclude: true });
      }
    }
    if (Array.isArray(body.excluded_tags)) {
      for (const tag of body.excluded_tags) {
        selectionsToInsert.push({ type: 'tag', shopify_gid: tag, value: tag, is_exclude: true });
      }
    }
    if (Array.isArray(body.excluded_products)) {
      for (const prod of body.excluded_products) {
        selectionsToInsert.push({ type: 'product', shopify_gid: prod.id, value: prod.title, is_exclude: true });
      }
    }

    if (selectionsToInsert.length > 0) {
      await db.setCatalogSelections(catalogId, selectionsToInsert);
    }

    // Run initial catalog sync so products are immediately synchronized with Meta
    try {
      await syncCatalog(catalogId);
    } catch (e: any) {
      console.error('[Initial Catalog Sync Error]:', e);
    }

    return NextResponse.json({
      success: true,
      catalog: newCatalog,
      message: 'Catalog created successfully',
    });
  } catch (err: any) {
    console.error('[API /api/catalogs POST] Error:', err);
    return NextResponse.json(
      { success: false, error: err.message || 'Failed to create catalog' },
      { status: 500 }
    );
  }
}
