import { NextRequest, NextResponse } from 'next/server';
import { db } from '@/db/client';
import { ShopRecord } from '@/types';
import { encrypt, decrypt } from '@/lib/crypto/encryption';
import { getAuthenticatedStore, unauthorizedResponse, extractShopDomainFromRequest } from '@/lib/auth/storeContext';
import { APP_CONFIG, APP_URLS, buildAppUrl } from '@/config/app';
import { SHOPIFY_CONFIG } from '@/config/shopify';
import { buildShopifyAuthUrl } from '@/lib/shopify/oauth';
import { canUseFeature } from '@/lib/shopify/plan-capability';

export const dynamic = 'force-dynamic';

export async function GET(req: NextRequest) {
  try {
    const shop = await getAuthenticatedStore(req);
    const requestedDomain =
      extractShopDomainFromRequest(req) ||
      req.nextUrl?.searchParams?.get('shop') ||
      req.nextUrl?.searchParams?.get('shopify_domain') ||
      SHOPIFY_CONFIG.defaultShopDomain;

    const shopDomain = shop ? shop.shopify_domain : requestedDomain;
    const shopId = shop ? shop.id : `shop_${shopDomain.replace(/[^a-zA-Z0-9]/g, '_')}`;

    const appConfig =
      (shop ? await db.getAppConfiguration(shop.id) : null) ||
      (await db.getAppConfigurationByDomain(shopDomain));
    const metaConn = shop ? await db.getMetaConnectionByShopId(shop.id) : null;
    const baseUrl = buildAppUrl();

    let hasShopifyToken = false;
    const shopifyEncrypted = appConfig?.shopify_access_token_encrypted || shop?.access_token_encrypted;
    if (shopifyEncrypted) {
      try {
        const decrypted = decrypt(shopifyEncrypted);
        hasShopifyToken = Boolean(decrypted && !decrypted.startsWith('mock_') && !decrypted.startsWith('shpat_mock_'));
      } catch {
        hasShopifyToken = false;
      }
    }

    const hasClientCredentials = Boolean(
      (appConfig?.shopify_api_key || process.env.SHOPIFY_API_KEY) &&
      (appConfig?.shopify_api_secret_encrypted || process.env.SHOPIFY_API_SECRET)
    );

    const businessId = appConfig?.meta_business_id || metaConn?.business_id || '';
    const businessName = appConfig?.meta_business_name || metaConn?.business_name || '';
    const catalogId = appConfig?.meta_catalog_id || metaConn?.catalog_id || '';
    const catalogName = appConfig?.meta_catalog_name || metaConn?.catalog_name || '';
    const pixelId = appConfig?.meta_pixel_id || metaConn?.pixel_id || '';
    const pixelName = appConfig?.meta_pixel_name || metaConn?.pixel_name || '';
    const testEventCode = appConfig?.meta_test_event_code || metaConn?.test_event_code || '';
    const hasMetaToken = Boolean(appConfig?.meta_access_token_encrypted || metaConn?.access_token_encrypted);

    const activeScopes = shop?.scopes && shop.scopes.length > 0 ? shop.scopes : SHOPIFY_CONFIG.scopesArray;

    return NextResponse.json({
      success: true,
      shop: {
        id: shop ? shop.id : shopId,
        domain: shopDomain,
        scopes: activeScopes,
        plan: shop?.plan || 'growth',
        installedAt: shop?.installed_at || new Date().toISOString(),
        status: shop ? shop.status : 'installed',
        hasShopifyToken: hasShopifyToken || hasClientCredentials,
      },
      shopifyApp: {
        name: APP_CONFIG.name,
        handle: 'meta-commerce-pixel-connector',
        clientId: appConfig?.shopify_api_key || SHOPIFY_CONFIG.apiKey,
        hasSecret: Boolean(appConfig?.shopify_api_secret_encrypted || process.env.SHOPIFY_API_SECRET),
        apiVersion: appConfig?.shopify_api_version || SHOPIFY_CONFIG.apiVersion,
        appUrl: baseUrl,
        embedded: true,
        hmacStatus: 'Timing-Safe Verified (crypto.timingSafeEqual)',
        scopes: activeScopes,
        grantedScopes: shop?.scopes || [],
        hasAllRequiredScopes: SHOPIFY_CONFIG.scopesArray.every((reqScope) => {
          const reqClean = reqScope.trim().toLowerCase();
          if ((shop?.scopes || []).some((g) => g.trim().toLowerCase() === reqClean)) return true;
          if (reqClean.startsWith('read_')) {
            const writeEq = reqClean.replace('read_', 'write_');
            if ((shop?.scopes || []).some((g) => g.trim().toLowerCase() === writeEq)) return true;
          }
          return false;
        }),
        reauthUrl: buildShopifyAuthUrl(shopDomain, APP_URLS.authCallback()).url,
        authEndpoint: buildAppUrl('/api/auth/shopify', { shop: shopDomain }),
        webhooks: [
          { topic: 'products/create', uri: buildAppUrl(APP_URLS.webhooks.shopify), status: 'Active' },
          { topic: 'products/update', uri: buildAppUrl(APP_URLS.webhooks.shopify), status: 'Active' },
          { topic: 'products/delete', uri: buildAppUrl(APP_URLS.webhooks.shopify), status: 'Active' },
          { topic: 'app/uninstalled', uri: buildAppUrl(APP_URLS.webhooks.shopify), status: 'Active' },
        ],
        gdprEndpoints: {
          customersDataRequest: buildAppUrl(APP_URLS.webhooks.shopifyGdpr),
          customersRedact: buildAppUrl(APP_URLS.webhooks.shopifyGdpr),
          shopRedact: buildAppUrl(APP_URLS.webhooks.shopifyGdpr),
        },
      },
      meta: {
        businessId,
        businessName,
        catalogId,
        catalogName,
        pixelId,
        pixelName,
        testEventCode,
        status: (pixelId || catalogId || businessId) ? 'connected' : 'disconnected',
        hasAccessToken: hasMetaToken,
      },
      endpoints: {
        xmlFeedUrl: buildAppUrl(`${APP_URLS.catalogUrls.feedXml}?shop=${shopDomain}`),
        csvFeedUrl: buildAppUrl(`${APP_URLS.catalogUrls.feedCsv}?shop=${shopDomain}`),
        capiWebhookUrl: buildAppUrl(APP_URLS.webhooks.shopify),
      },
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Internal Server Error' },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    let shop = await getAuthenticatedStore(req);
    const body = await req.json();
    const requestedDomain = (
      body.shopDomain ||
      extractShopDomainFromRequest(req) ||
      req.nextUrl?.searchParams?.get('shop') ||
      SHOPIFY_CONFIG.defaultShopDomain
    ).trim().toLowerCase();

    if (!shop) {
      shop = await db.getShopByDomain(requestedDomain);
      if (!shop) {
        const now = new Date().toISOString();
        const newShopRecord: ShopRecord = {
          id: `shop_${requestedDomain.replace(/[^a-zA-Z0-9]/g, '_')}`,
          shopify_domain: requestedDomain,
          access_token_encrypted: '',
          status: 'installed',
          scopes: SHOPIFY_CONFIG.scopesArray,
          plan: 'growth',
          installed_at: now,
          created_at: now,
          updated_at: now,
        };
        shop = await db.upsertShop(newShopRecord);
      }
    }

    const targetShop: ShopRecord = shop;

    const {
      businessId,
      businessName,
      catalogId,
      catalogName,
      pixelId,
      pixelName,
      accessToken,
      shopifyAccessToken,
      shopifyApiKey,
      shopifyApiSecret,
      testEventCode,
      restrictedMode,
    } = body;

    // Feature gating: Restricted Mode (Consent Policy / GDPR) is Scale Plan only
    if (restrictedMode === true && !canUseFeature(targetShop.plan, 'meta.restricted_mode')) {
      return NextResponse.json(
        {
          success: false,
          code: 'FEATURE_NOT_AVAILABLE',
          error: 'Restricted Mode (Consent Policy / GDPR) is exclusive to the Scale Plan. Please upgrade your subscription to enable consent policy protection.',
          upgradeUrl: '/meta-connector/pricing',
        },
        { status: 403 }
      );
    }

    const existingConfig = await db.getAppConfiguration(targetShop.id) || await db.getAppConfigurationByDomain(targetShop.shopify_domain);
    const existingMeta = await db.getMetaConnectionByShopId(targetShop.id);
    if (shopifyAccessToken !== undefined && shopifyAccessToken.trim() !== '') {
      if (shopifyAccessToken.trim().startsWith('shpss_')) {
        return NextResponse.json(
          {
            success: false,
            error: 'The value entered is an App API Secret Key (starts with "shpss_"), NOT an Admin API Access Token. A Shopify Admin API Access Token must start with "shpat_". Please generate and copy the Admin API access token under Shopify Admin > Settings > Apps and sales channels > Develop apps.',
          },
          { status: 400 }
        );
      }
    }

    const shopifyTokenEncrypted = shopifyAccessToken !== undefined && shopifyAccessToken.trim() !== ''
      ? encrypt(shopifyAccessToken.trim())
      : existingConfig?.shopify_access_token_encrypted || targetShop.access_token_encrypted || null;

    const metaTokenEncrypted = accessToken !== undefined && accessToken.trim() !== ''
      ? encrypt(accessToken.trim())
      : existingConfig?.meta_access_token_encrypted || existingMeta?.access_token_encrypted || null;

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

    const updatedConfig = {
      id: existingConfig?.id || `config_${targetShop.id}`,
      shop_id: targetShop.id,
      shopify_domain: targetShop.shopify_domain,
      shopify_access_token_encrypted: shopifyTokenEncrypted,
      shopify_api_key: shopifyApiKey !== undefined ? shopifyApiKey : existingConfig?.shopify_api_key || SHOPIFY_CONFIG.apiKey || null,
      shopify_api_secret_encrypted: shopifyApiSecret ? encrypt(shopifyApiSecret) : existingConfig?.shopify_api_secret_encrypted || null,
      shopify_api_version: existingConfig?.shopify_api_version || SHOPIFY_CONFIG.apiVersion,
      meta_business_id: businessId !== undefined ? businessId : existingConfig?.meta_business_id || null,
      meta_business_name: businessName !== undefined ? businessName : existingConfig?.meta_business_name || null,
      meta_catalog_id: catalogId !== undefined ? catalogId : existingConfig?.meta_catalog_id || null,
      meta_catalog_name: catalogName !== undefined ? catalogName : existingConfig?.meta_catalog_name || null,
      meta_pixel_id: pixelId !== undefined ? pixelId : existingConfig?.meta_pixel_id || null,
      meta_pixel_name: pixelName !== undefined ? pixelName : existingConfig?.meta_pixel_name || null,
      meta_access_token_encrypted: metaTokenEncrypted,
      meta_test_event_code: testEventCode !== undefined ? testEventCode : existingConfig?.meta_test_event_code || null,
      created_at: existingConfig?.created_at || now,
      updated_at: now,
    };

    await db.upsertAppConfiguration(updatedConfig);

    // Sync shops table
    if (shopifyTokenEncrypted) {
      await db.upsertShop({
        ...targetShop,
        access_token_encrypted: shopifyTokenEncrypted,
        status: 'installed',
        updated_at: now,
      });
    }

    // Sync meta_connections table
    const updatedMetaConn = {
      id: existingMeta?.id || `meta_${targetShop.id}`,
      shop_id: targetShop.id,
      business_id: updatedConfig.meta_business_id,
      business_name: updatedConfig.meta_business_name,
      catalog_id: updatedConfig.meta_catalog_id,
      catalog_name: updatedConfig.meta_catalog_name,
      pixel_id: updatedConfig.meta_pixel_id,
      pixel_name: updatedConfig.meta_pixel_name,
      access_token_encrypted: metaTokenEncrypted || '',
      test_event_code: updatedConfig.meta_test_event_code,
      status: (updatedConfig.meta_pixel_id || updatedConfig.meta_catalog_id) ? ('connected' as const) : ('disconnected' as const),
      created_at: existingMeta?.created_at || now,
      updated_at: now,
    };
    await db.upsertMetaConnection(updatedMetaConn);

    return NextResponse.json({
      success: true,
      message: `Shopify & Meta Configuration details saved successfully to database for ${shop.shopify_domain}`,
      configuration: updatedConfig,
    });
  } catch (err) {
    return NextResponse.json(
      { success: false, error: err instanceof Error ? err.message : 'Internal Server Error' },
      { status: 500 }
    );
  }
}
