import { NextRequest, NextResponse } from 'next/server';
import { exchangeShopifyAuthCode } from '@/lib/shopify/oauth';
import { verifyShopifyOAuthQuery } from '@/lib/shopify/hmac';
import { db } from '@/db/client';
import { encrypt } from '@/lib/crypto/encryption';
import { logger } from '@/lib/logger';
import { ShopRecord } from '@/types';
import { buildAppUrl } from '@/config/app';
import { SHOPIFY_CONFIG } from '@/config/shopify';
import { clearCachedShopifyToken } from '@/lib/shopify/token-manager';

export const dynamic = 'force-dynamic';

export async function GET(req: NextRequest) {
  const { searchParams } = new URL(req.url);
  const shop = searchParams.get('shop');
  const code = searchParams.get('code');
  const hmac = searchParams.get('hmac');

  if (!shop || !code) {
    return NextResponse.json({ error: 'Missing shop or code parameter' }, { status: 400 });
  }

  // Verify HMAC signature in production
  const isDev = process.env.NODE_ENV !== 'production' || process.env.SHOPIFY_API_SECRET?.startsWith('mock_');
  if (!isDev && hmac) {
    const queryObj: Record<string, string> = {};
    searchParams.forEach((val, key) => { queryObj[key] = val; });
    const isValid = verifyShopifyOAuthQuery(queryObj);
    if (!isValid) {
      return NextResponse.json({ error: 'Invalid OAuth HMAC signature' }, { status: 401 });
    }
  }

  try {
    const existing = await db.getShopByDomain(shop);
    const authResult = await exchangeShopifyAuthCode(shop, code);
    const { access_token, scope, expires_in, refresh_token, refresh_token_expires_in } = authResult;
    clearCachedShopifyToken(shop);
    const now = new Date().toISOString();
    const tokenExpiresAt = expires_in ? new Date(Date.now() + expires_in * 1000).toISOString() : existing?.token_expires_at || null;
    const refreshTokenExpiresAt = refresh_token_expires_in
      ? new Date(Date.now() + refresh_token_expires_in * 1000).toISOString()
      : (refresh_token ? new Date(Date.now() + 90 * 86400 * 1000).toISOString() : existing?.refresh_token_expires_at || null);

    const isReinstall = Boolean(existing && (existing.status === 'uninstalled' || existing.uninstalled_at));

    // Attempt to enrich store profile with live Shopify shop info
    let shopDetails: any = null;
    try {
      const shopRes = await fetch(`https://${shop}/admin/api/${SHOPIFY_CONFIG.apiVersion}/shop.json`, {
        headers: { 'X-Shopify-Access-Token': access_token },
      });
      if (shopRes.ok) {
        const body = await shopRes.json();
        shopDetails = body?.shop;
      }
    } catch {}

    const grantedList = scope ? scope.split(',').map(s => s.trim()) : SHOPIFY_CONFIG.scopesArray;
    if (grantedList.includes('write_products') && !grantedList.includes('read_products')) {
      grantedList.push('read_products');
    }

    const shopRecord: ShopRecord = {
      id: existing?.id || `shop_${Date.now()}`,
      shopify_domain: shop,
      shopify_shop_id: shopDetails?.id ? `gid://shopify/Shop/${shopDetails.id}` : existing?.shopify_shop_id,
      shop_name: shopDetails?.name || existing?.shop_name || shop.replace('.myshopify.com', ''),
      owner_email: shopDetails?.email || existing?.owner_email || null,
      owner_name: shopDetails?.shop_owner || existing?.owner_name || null,
      country: shopDetails?.country_name || shopDetails?.country_code || existing?.country || 'US',
      currency: shopDetails?.currency || existing?.currency || 'USD',
      billing_cycle: existing?.billing_cycle || 'monthly',
      monthly_revenue: existing?.monthly_revenue ?? 0,
      last_active_at: now,
      access_token_encrypted: encrypt(access_token),
      refresh_token_encrypted: refresh_token ? encrypt(refresh_token) : existing?.refresh_token_encrypted || null,
      token_expires_at: tokenExpiresAt,
      refresh_token_expires_at: refreshTokenExpiresAt,
      token_updated_at: now,
      scopes: grantedList,
      installed_at: existing?.installed_at || now,
      uninstalled_at: null,
      status: 'installed',
      plan: existing?.plan || 'basic',
      subscription_status: existing?.subscription_status || 'free',
      created_at: existing?.created_at || now,
      updated_at: now,
    };

    await db.upsertShop(shopRecord);
    logger.info(`Successfully authenticated Shopify shop: ${shop} (isReinstall=${isReinstall})`);

    // Authoritative billing sync against Shopify GraphQL
    try {
      const { BillingService } = await import('@/lib/shopify/billing');
      await BillingService.syncSubscription(shop);
    } catch (syncErr) {
      logger.warn(`Could not sync subscription during install for ${shop}`, { error: String(syncErr) });
    }

    // Track installation event
    await db.recordAppInstallation({
      id: `inst_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`,
      shop_id: shopRecord.id,
      shopify_domain: shop,
      event_type: isReinstall ? 'reinstalled' : 'installed',
      plan_at_time: shopRecord.plan,
      metadata: {
        shopify_shop_id: shopDetails?.id,
        shop_name: shopRecord.shop_name,
        owner_email: shopRecord.owner_email,
        country: shopRecord.country,
      },
      occurred_at: now,
      created_at: now,
    });

    // Record activity log
    await db.recordStoreActivity({
      id: `act_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`,
      shop_id: shopRecord.id,
      shopify_domain: shop,
      action: isReinstall ? 'app_reinstalled' : 'app_installed',
      actor: 'merchant',
      description: isReinstall
        ? `Merchant reinstalled app on ${shop}`
        : `New store installation completed on ${shop} (${shopRecord.shop_name})`,
      metadata: { isReinstall, shop_name: shopRecord.shop_name },
      created_at: now,
    });

    // Update app_configurations
    const existingConfig = await db.getAppConfiguration(shopRecord.id) || await db.getAppConfigurationByDomain(shop);
    await db.upsertAppConfiguration({
      id: existingConfig?.id || `config_${shopRecord.id}`,
      shop_id: shopRecord.id,
      shopify_domain: shop,
      shopify_access_token_encrypted: encrypt(access_token),
      shopify_api_key: SHOPIFY_CONFIG.apiKey || null,
      shopify_api_secret_encrypted: SHOPIFY_CONFIG.getServerSecret() ? encrypt(SHOPIFY_CONFIG.getServerSecret()) : null,
      shopify_api_version: SHOPIFY_CONFIG.apiVersion,
      meta_business_id: existingConfig?.meta_business_id || null,
      meta_business_name: existingConfig?.meta_business_name || null,
      meta_catalog_id: existingConfig?.meta_catalog_id || null,
      meta_catalog_name: existingConfig?.meta_catalog_name || null,
      meta_pixel_id: existingConfig?.meta_pixel_id || null,
      meta_pixel_name: existingConfig?.meta_pixel_name || null,
      meta_access_token_encrypted: existingConfig?.meta_access_token_encrypted || null,
      meta_test_event_code: existingConfig?.meta_test_event_code || null,
      created_at: existingConfig?.created_at || now,
      updated_at: now,
    });

    const host = searchParams.get('host');
    const appIdentifier = process.env.SHOPIFY_APP_HANDLE || 'meta-sync-pixel-connector-1';
    const sanitizedShop = shop.toLowerCase().replace(/^https?:\/\//, '').replace('.myshopify.com', '').replace(/\/.*$/, '');
    let destinationUrl = `https://admin.shopify.com/store/${sanitizedShop}/apps/${appIdentifier}/meta-connector/pixel`;

    if (host) {
      try {
        const decodedHost = Buffer.from(host, 'base64').toString('utf8');
        destinationUrl = `https://${decodedHost}/apps/${appIdentifier}/meta-connector/pixel`;
      } catch {
        destinationUrl = `https://admin.shopify.com/store/${sanitizedShop}/apps/${appIdentifier}/meta-connector/pixel`;
      }
    }

    const response = NextResponse.redirect(destinationUrl);
    response.cookies.set('shopify_shop_domain', shop.toLowerCase().trim(), {
      path: '/',
      httpOnly: false,
      sameSite: 'none',
      secure: true,
      maxAge: 86400 * 30,
    });
    return response;
  } catch (err) {
    logger.error('Failed to complete Shopify OAuth callback', err);
    return NextResponse.json(
      { error: err instanceof Error ? err.message : 'Authentication failed' },
      { status: 500 }
    );
  }
}
