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, CatalogSelectionRecord } from '@/types/catalog';

export const dynamic = 'force-dynamic';

export async function GET(
  req: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const shop = await getAuthenticatedStore(req);
    if (!shop) {
      return unauthorizedResponse();
    }
    const catalogId = params.id;
    if (!catalogId) {
      return NextResponse.json({ success: false, error: 'Invalid catalog ID' }, { status: 400 });
    }

    const catalog = await db.getCatalogById(catalogId);
    if (!catalog || catalog.shop_id !== shop.id) {
      return NextResponse.json({ success: false, error: 'Catalog not found' }, { status: 404 });
    }

    const selections = await db.getCatalogSelections(catalogId);
    let shopProducts: any[] = [];
    try {
      shopProducts = await db.getProductsByShopId(shop.id);
    } catch {}

    const enrichedSelections = selections.map(s => {
      if (s.type === 'product') {
        const prodGid = s.shopify_gid;
        const prodNum = prodGid.replace(/^gid:\/\/shopify\/Product\//, '');
        const matched = shopProducts.find(
          p => p.shopify_product_id === prodGid || p.shopify_product_id.includes(prodNum)
        );
        return {
          ...s,
          value: matched?.title || s.value || `Product #${prodNum}`,
          title: matched?.title || s.value || `Product #${prodNum}`,
          image: matched?.image_url || '',
          price: matched?.price,
        };
      }
      return s;
    });

    return NextResponse.json({
      success: true,
      catalog,
      selections: enrichedSelections,
      fbCommerceManagerUrl: catalog.fb_catalog_url || MetaCatalogService.getCommerceManagerUrl(
        catalog.fb_catalog_id,
        catalog.fb_business_id
      ),
    });
  } catch (err: any) {
    console.error('[API /api/catalogs/[id] GET] Error:', err);
    return NextResponse.json(
      { success: false, error: err.message || 'Failed to fetch catalog' },
      { status: 500 }
    );
  }
}

export async function PUT(
  req: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const shop = await getAuthenticatedStore(req);
    if (!shop) {
      return unauthorizedResponse();
    }
    const catalogId = params.id;
    if (!catalogId) {
      return NextResponse.json({ success: false, error: 'Invalid catalog ID' }, { status: 400 });
    }

    const catalog = await db.getCatalogById(catalogId);
    if (!catalog || catalog.shop_id !== shop.id) {
      return NextResponse.json({ success: false, error: 'Catalog not found' }, { status: 404 });
    }

    // Server-side Gate: Facebook connection 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 }
      );
    }

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

    if (body.name !== undefined && !body.name.trim()) {
      return NextResponse.json({ success: false, error: 'Catalog name cannot be empty' }, { status: 400 });
    }
    if (body.name && body.name.trim().length > 150) {
      return NextResponse.json({ success: false, error: 'Catalog name cannot exceed 150 characters' }, { status: 400 });
    }

    if (body.sync_scope === 'selected') {
      const hasCollections = Array.isArray(body.selected_collections) && body.selected_collections.length > 0;
      const hasTags = Array.isArray(body.selected_tags) && body.selected_tags.length > 0;
      const hasProducts = Array.isArray(body.selected_products) && body.selected_products.length > 0;
      if (!hasCollections && !hasTags && !hasProducts) {
        return NextResponse.json({ success: false, error: 'Please select at least one collection, tag, or product to sync' }, { status: 400 });
      }
    }

    if (body.link_domain === 'custom' && (!body.custom_domain || !body.custom_domain.trim())) {
      return NextResponse.json({ success: false, error: 'Custom domain is required when Custom Domain is selected' }, { status: 400 });
    }

    const nextSync = body.auto_sync !== false
      ? calculateNextSyncDate(
          body.schedule_type || catalog.schedule_type || 'daily',
          body.schedule_day || catalog.schedule_day || 'Every Monday',
          body.schedule_hour || catalog.schedule_hour || 2,
          body.schedule_period || catalog.schedule_period || 'AM',
          body.schedule_tz || catalog.schedule_tz || 'UTC'
        )
      : null;

    const nowIso = new Date().toISOString();

    const updatedFbCatalogId = body.fb_catalog_id ? body.fb_catalog_id.trim() : catalog.fb_catalog_id;
    const updatedBusinessId = body.business_id ? body.business_id.trim() : catalog.fb_business_id;
    const updatedFbUrl = MetaCatalogService.getCommerceManagerUrl(updatedFbCatalogId, updatedBusinessId);

    await db.updateCatalog(catalogId, {
      name: body.name ? body.name.trim() : catalog.name,
      fb_catalog_id: updatedFbCatalogId,
      fb_business_id: updatedBusinessId,
      fb_catalog_url: updatedFbUrl,
      fb_pixel_id: body.pixel_id !== undefined ? body.pixel_id : catalog.fb_pixel_id,
      sync_scope: body.sync_scope || catalog.sync_scope,
      variant_mode: body.variant_mode || catalog.variant_mode,
      google_category_id: body.google_category_id !== undefined ? body.google_category_id : catalog.google_category_id,
      google_category_name: body.google_category_name !== undefined ? body.google_category_name : catalog.google_category_name,
      additional_images: body.additional_images !== undefined ? body.additional_images : catalog.additional_images,
      link_domain: body.link_domain || catalog.link_domain,
      custom_domain: body.link_domain === 'custom' ? (body.custom_domain?.trim() || null) : (body.custom_domain !== undefined ? body.custom_domain : catalog.custom_domain),
      exclude_out_of_stock: body.exclude_out_of_stock !== undefined ? Boolean(body.exclude_out_of_stock) : catalog.exclude_out_of_stock,
      price_mode: body.price_mode || catalog.price_mode,
      schedule_type: body.schedule_type || catalog.schedule_type,
      schedule_day: body.schedule_day || catalog.schedule_day,
      schedule_hour: body.schedule_hour || catalog.schedule_hour,
      schedule_period: body.schedule_period || catalog.schedule_period,
      schedule_tz: body.schedule_tz || catalog.schedule_tz,
      auto_sync: body.auto_sync !== undefined ? body.auto_sync : catalog.auto_sync,
      pixel_tracking: body.pixel_tracking !== undefined ? body.pixel_tracking : catalog.pixel_tracking,
      next_sync_at: nextSync,
      updated_at: nowIso,
    });

    // Update selections
    const selectionsToSave: Array<Omit<CatalogSelectionRecord, 'id' | 'catalog_id'>> = [];

    if (body.sync_scope === 'selected') {
      if (body.selected_collections) {
        body.selected_collections.forEach(c => {
          selectionsToSave.push({
            type: 'collection',
            shopify_gid: `gid://shopify/Collection/${c.id}`,
            value: c.title,
            is_exclude: false,
          });
        });
      }
      if (body.selected_tags) {
        body.selected_tags.forEach(t => {
          selectionsToSave.push({
            type: 'tag',
            shopify_gid: `tag:${t}`,
            value: t,
            is_exclude: false,
          });
        });
      }
      if (body.selected_products) {
        body.selected_products.forEach(p => {
          selectionsToSave.push({
            type: 'product',
            shopify_gid: `gid://shopify/Product/${p.id}`,
            value: '',
            is_exclude: false,
          });
        });
      }
    }

    if (body.excluded_tags && Array.isArray(body.excluded_tags)) {
      body.excluded_tags.forEach(t => {
        if (t && t.trim()) {
          selectionsToSave.push({
            type: 'tag',
            shopify_gid: `tag:${t.trim()}`,
            value: t.trim(),
            is_exclude: true,
          });
        }
      });
    }

    if (body.excluded_collections && Array.isArray(body.excluded_collections)) {
      body.excluded_collections.forEach(c => {
        if (c && c.id) {
          selectionsToSave.push({
            type: 'collection',
            shopify_gid: `gid://shopify/Collection/${c.id}`,
            value: c.title || '',
            is_exclude: true,
          });
        }
      });
    }

    if (body.excluded_products && Array.isArray(body.excluded_products)) {
      body.excluded_products.forEach(p => {
        if (p && p.id) {
          selectionsToSave.push({
            type: 'product',
            shopify_gid: `gid://shopify/Product/${p.id}`,
            value: p.title || '',
            is_exclude: true,
          });
        }
      });
    }

    await db.setCatalogSelections(catalogId, selectionsToSave);

    // Sync updated catalog to Meta
    let syncResult = null;
    try {
      syncResult = await syncCatalog(catalogId);
    } catch (syncErr: any) {
      console.warn('[API /api/catalogs/[id] PUT] Sync error:', syncErr.message);
      syncResult = {
        success: false,
        catalogId,
        fbCatalogId: catalog.fb_catalog_id,
        totalVariants: 0,
        upsertedCount: 0,
        deletedCount: 0,
        error: syncErr.message || 'Sync failed',
      };
    }

    const updated = await db.getCatalogById(catalogId);

    return NextResponse.json({
      success: true,
      catalog: updated,
      syncResult,
    });
  } catch (err: any) {
    console.error('[API /api/catalogs/[id] PUT] Error:', err);
    return NextResponse.json(
      { success: false, error: err.message || 'Failed to update catalog' },
      { status: 500 }
    );
  }
}

export async function DELETE(
  req: NextRequest,
  { params }: { params: { id: string } }
) {
  try {
    const shop = await getAuthenticatedStore(req);
    if (!shop) {
      return unauthorizedResponse();
    }
    const catalogId = params.id;
    if (!catalogId) {
      return NextResponse.json({ success: false, error: 'Invalid catalog ID' }, { status: 400 });
    }

    const catalog = await db.getCatalogById(catalogId);
    if (!catalog || catalog.shop_id !== shop.id) {
      return NextResponse.json({ success: false, error: 'Catalog not found' }, { status: 404 });
    }

    // Server-side Gate: Facebook connection 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 && catalog.fb_catalog_id && !catalog.fb_catalog_id.startsWith('cat_')) {
      try {
        await MetaCatalogService.deleteCatalog(catalog.fb_catalog_id, accessToken);
      } catch (fbErr) {
        console.warn('[API /api/catalogs/[id] DELETE] Meta Graph API delete warning:', fbErr);
      }
    }

    await db.deleteCatalog(catalogId);

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