import crypto from 'crypto';
import { env } from '@/lib/config/env';

/**
 * Validates Shopify Webhook HMAC header (X-Shopify-Hmac-Sha256) against raw request body.
 */
export function verifyShopifyWebhookHmac(rawBody: string | Buffer, hmacHeader: string, secret?: string): boolean {
  const apiSecret = secret || env.shopify.apiSecret;
  if (!apiSecret || !hmacHeader) return false;

  const generatedHmac = crypto
    .createHmac('sha256', apiSecret)
    .update(rawBody)
    .digest('base64');

  try {
    const generatedBuffer = Buffer.from(generatedHmac, 'utf8');
    const headerBuffer = Buffer.from(hmacHeader, 'utf8');
    
    if (generatedBuffer.length !== headerBuffer.length) {
      return false;
    }
    return crypto.timingSafeEqual(generatedBuffer, headerBuffer);
  } catch {
    return false;
  }
}

/**
 * Validates Shopify OAuth callback query string HMAC signature.
 */
export function verifyShopifyOAuthQuery(query: Record<string, string | string[] | undefined>, secret?: string): boolean {
  const apiSecret = secret || process.env.SHOPIFY_API_SECRET;
  const hmac = typeof query.hmac === 'string' ? query.hmac : undefined;
  if (!apiSecret || !hmac) return false;

  // Shopify OAuth HMAC verification:
  // 1. Remove 'hmac' and 'signature' from the query parameters
  // 2. Sort the keys alphabetically
  // 3. Form key=value pairs joined with &
  const keys = Object.keys(query)
    .filter((k) => k !== 'hmac' && k !== 'signature')
    .sort();

  const message = keys
    .map((k) => `${k}=${Array.isArray(query[k]) ? (query[k] as string[]).join(',') : query[k]}`)
    .join('&');

  const calculatedHmac = crypto
    .createHmac('sha256', apiSecret)
    .update(message)
    .digest('hex');

  try {
    const calculatedBuffer = Buffer.from(calculatedHmac, 'utf8');
    const hmacBuffer = Buffer.from(hmac, 'utf8');
    if (calculatedBuffer.length !== hmacBuffer.length) {
      return false;
    }
    return crypto.timingSafeEqual(calculatedBuffer, hmacBuffer);
  } catch {
    return false;
  }
}

/**
 * Validates a myshopify domain string to prevent SSRF and open redirects.
 */
export function isValidShopifyDomain(shop: string): boolean {
  if (!shop) return false;
  // Match standard myshopify domain format, e.g. "store-name.myshopify.com"
  const shopRegex = /^[a-zA-Z0-9][a-zA-Z0-9\-_]*\.myshopify\.com$/i;
  return shopRegex.test(shop.trim());
}
