import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { wrapHandler } from '../_shared/error-handler.ts'

// Helper function to convert ArrayBuffer to hex string
function bufferToHex(buffer: ArrayBuffer): string {
  const byteArray = new Uint8Array(buffer);
  return Array.from(byteArray)
    .map((byte) => byte.toString(16).padStart(2, "0"))
    .join("");
}

// Calculate HMAC-SHA256 using Deno's native crypto.subtle API
async function calculateHmacSha256(secret: string, message: string): Promise<string> {
  const encoder = new TextEncoder();
  const keyData = encoder.encode(secret);
  const key = await crypto.subtle.importKey(
    "raw",
    keyData,
    { name: "HMAC", hash: { name: "SHA-256" } },
    false,
    ["sign"]
  );
  const messageData = encoder.encode(message);
  const signature = await crypto.subtle.sign("HMAC", key, messageData);
  return bufferToHex(signature);
}

import { getCorsHeaders, handleCorsPreflightRequest } from '../_shared/cors.ts';


// Validate HMAC signature from ShopRenter
// Per ShopRenter documentation, HMAC is calculated from the query string without HMAC parameter
// IMPORTANT: Parameter order MUST match exactly as ShopRenter sends them: shopname, code, timestamp
async function validateHMAC(shopname: string, code: string, timestamp: string, hmac: string, clientSecret: string, clientId: string): Promise<boolean> {
  if (!clientSecret) {
    console.error('[ShopRenter] Client secret is empty or undefined')
    return false
  }

  if (!hmac) {
    console.error('[ShopRenter] HMAC missing from request')
    return false
  }

  // Build the params string in the EXACT order ShopRenter uses: shopname, code, timestamp
  // This order is critical - ShopRenter calculates HMAC using this specific order
  const paramsWithoutHmac = `shopname=${shopname}&code=${code}&timestamp=${timestamp}`

  console.log(`[ShopRenter] HMAC validation - params (fixed order): ${paramsWithoutHmac}`)

  // Calculate HMAC using Deno's native crypto.subtle API (SHA-256)
  const calculatedHmacWithSecret = await calculateHmacSha256(clientSecret, paramsWithoutHmac)

  console.log(`[ShopRenter] HMAC validation - received hmac: ${hmac}`)
  console.log(`[ShopRenter] HMAC validation - calculated hmac (with secret): ${calculatedHmacWithSecret}`)

  // Compare HMACs
  const resultWithSecret = calculatedHmacWithSecret === hmac
  console.log(`[ShopRenter] HMAC validation result (with secret): ${resultWithSecret}`)

  if (resultWithSecret) {
    return true
  }

  // Fallback: try with Client ID (in case of documentation confusion)
  const calculatedHmacWithId = await calculateHmacSha256(clientId, paramsWithoutHmac)
  console.log(`[ShopRenter] HMAC validation - calculated hmac (with id): ${calculatedHmacWithId}`)

  const resultWithId = calculatedHmacWithId === hmac
  console.log(`[ShopRenter] HMAC validation result (with id): ${resultWithId}`)

  return resultWithId
}

serve(wrapHandler('validate-shoprenter-hmac', async (req) => {
  const origin = req.headers.get('Origin') || undefined;
  const corsHeaders = getCorsHeaders(origin);

  if (req.method === 'OPTIONS') {
    return handleCorsPreflightRequest(origin)
  }

  try {
    // Parse request body containing the URL parameters
    const body = await req.json()
    const { shopname, code, timestamp, hmac, sr_install } = body

    console.log(`[ShopRenter] Validating HMAC for ${shopname}`)

    // Check required parameters
    if (!shopname || !code || !timestamp || !hmac) {
      return new Response(
        JSON.stringify({ valid: false, error: 'Missing required parameters' }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    // Get environment variables (support both naming conventions with fallback)
    const shoprenterClientId = Deno.env.get('SHOPRENTER_APP_CLIENT_ID') || Deno.env.get('SHOPRENTER_CLIENT_ID')
    const shoprenterClientSecret = Deno.env.get('SHOPRENTER_APP_CLIENT_SECRET') || Deno.env.get('SHOPRENTER_CLIENT_SECRET')

    if (!shoprenterClientId || !shoprenterClientSecret) {
      console.error('ShopRenter client credentials not configured')
      return new Response(
        JSON.stringify({ valid: false, error: 'ShopRenter integration not configured' }),
        { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    // Validate HMAC with exact parameter order
    const isValid = await validateHMAC(shopname, code, timestamp, hmac, shoprenterClientSecret, shoprenterClientId)

    if (!isValid) {
      console.error(`[ShopRenter] HMAC validation failed for ${shopname}`)
      return new Response(
        JSON.stringify({ valid: false, error: 'HMAC validation failed' }),
        { status: 403, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    console.log(`[ShopRenter] HMAC validation successful for ${shopname}`)

    return new Response(
      JSON.stringify({
        valid: true,
        shopname,
        installation_id: sr_install
      }),
      { status: 200, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )

  } catch (error) {
    console.error('[ShopRenter] HMAC validation error:', error)
    return new Response(
      JSON.stringify({ valid: false, error: 'Failed to validate HMAC' }),
      { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }
}))
