import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
import fetchHelper from "../../../utils/fetchHelper"

// POST /api/shopify/stocks/sync
// Syncs local qty on hand to Shopify via REST API
// Body: { orderSourceId, variantId (SKU), inventoryItemId?, quantity, sku?, productId? }
//
// Shopify Inventory Level Set API:
// POST /admin/api/2024-01/inventory_levels/set.json
const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const body = await readBody(event)

  const { orderSourceId, variantId, quantity, sku, productId, locationId: bodyLocationId } = body
  let { inventoryItemId } = body

  if(!orderSourceId) {
    return { status: 400, message: 'orderSourceId is required', success: false }
  }
  if(!variantId) {
    return { status: 400, message: 'variantId (SKU) is required', success: false }
  }
  if(quantity === undefined || quantity === null) {
    return { status: 400, message: 'quantity is required', success: false }
  }

  // Load order source to verify it's Shopify and get credentials
  const os: any = await fetchHelper(event, `models/c_ordersource/${orderSourceId}`, 'GET', token, null)
  if(!os) {
    return { status: 404, message: 'Order Source not found', success: false }
  }
  if(os?.Marketplace?.identifier !== 'shopify') {
    return { status: 400, message: 'Selected Order Source is not Shopify', success: false }
  }

  // Get Shopify credentials from order source
  const shopUrl = os?.marketplace_url || ''
  const accessToken = os?.marketplace_token || os?.marketplace_secret || ''

  if(!shopUrl) {
    return { status: 400, message: 'No marketplace_url configured for this Order Source', success: false }
  }
  if(!accessToken) {
    return { status: 400, message: 'No marketplace_token or marketplace_secret configured for this Order Source', success: false }
  }

  // Get Shopify location ID (required for setting inventory)
  const locationId = os?.Shopify_Location_ID || null

  try {
    // Normalize shop URL
    let host = shopUrl.trim()
    if(!/^https?:\/\//i.test(host)) host = `https://${host}`
    host = host.replace(/\/$/, '')
    if(!host.includes('.myshopify.com') && !host.includes('/admin')) {
      const shopName = host.replace(/^https?:\/\//i, '').split('.')[0]
      host = `https://${shopName}.myshopify.com`
    }

    const apiBase = `${host}/admin/api/2024-01`

    const authHeaders = {
      'X-Shopify-Access-Token': accessToken,
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }

    const targetQty = Number(quantity)
    const skuToFind = String(variantId).toLowerCase()

    // If inventoryItemId is provided, use it directly (from previous fetch)
    if(inventoryItemId) {
      console.log(`Using provided inventoryItemId: ${inventoryItemId} for SKU "${variantId}"`)
    }

    // If inventoryItemId is not provided, search for SKU in products using REST API
    if(!inventoryItemId) {
      console.log(`Searching for SKU "${skuToFind}" in Shopify products...`)

      // Fetch products and find matching SKU using since_id pagination
      let sinceId = 0
      let found = false
      const limit = 250
      let pageNum = 1

      while(!found && pageNum <= 50) {
        try {
          const productsUrl = `${apiBase}/products.json?limit=${limit}&since_id=${sinceId}`
          const productsRes: any = await $fetch(productsUrl, {
            method: 'GET',
            headers: authHeaders
          })

          const products = productsRes?.products || []
          if(products.length === 0) break

          for(const product of products) {
            const variants = product.variants || []
            for(const variant of variants) {
              if(String(variant.sku || '').toLowerCase() === skuToFind) {
                inventoryItemId = String(variant.inventory_item_id)
                console.log(`Found SKU "${skuToFind}" -> inventory_item_id: ${inventoryItemId}`)
                found = true
                break
              }
            }
            if(found) break
            // Update since_id to the last product's ID
            if(product.id) sinceId = product.id
          }

          if(products.length < limit) break
          pageNum++
        } catch (err: any) {
          console.error(`Failed to fetch products (since_id=${sinceId}):`, err?.message)
          break
        }
      }
    }

    if(!inventoryItemId) {
      return {
        status: 400,
        success: false,
        message: `Could not find variant with SKU "${variantId}" in Shopify.`,
        variantId
      }
    }

    // Get location ID - prioritize: body param > order source config > fetch from API
    let effectiveLocationId = bodyLocationId || locationId
    if(!effectiveLocationId) {
      try {
        const locationsUrl = `${apiBase}/locations.json`
        const locationsRes: any = await $fetch(locationsUrl, {
          method: 'GET',
          headers: authHeaders
        })
        if(locationsRes?.locations && locationsRes.locations.length > 0) {
          const activeLocation = locationsRes.locations.find((l: any) => l.active) || locationsRes.locations[0]
          effectiveLocationId = String(activeLocation.id)
          console.log('Using Shopify location:', effectiveLocationId)
        }
      } catch (locErr: any) {
        console.error('Failed to fetch Shopify locations:', locErr?.message)
        return {
          status: 400,
          success: false,
          message: 'Could not determine Shopify location. Please configure Shopify_Location_ID on the order source.',
          variantId
        }
      }
    }

    if(!effectiveLocationId) {
      return {
        status: 400,
        success: false,
        message: 'No Shopify location found. Please configure Shopify_Location_ID on the order source.',
        variantId
      }
    }

    // Set inventory level using REST API
    // POST /admin/api/2024-01/inventory_levels/set.json
    const setUrl = `${apiBase}/inventory_levels/set.json`
    const setBody = {
      location_id: Number(effectiveLocationId),
      inventory_item_id: Number(inventoryItemId),
      available: targetQty
    }

    console.log('Shopify inventory set request:', { url: setUrl, body: setBody })

    const result: any = await $fetch(setUrl, {
      method: 'POST',
      headers: authHeaders,
      body: setBody
    })

    console.log('Shopify inventory set response:', JSON.stringify(result).slice(0, 800))

    const updatedStock = result?.inventory_level?.available ?? targetQty

    return {
      status: 200,
      success: true,
      message: `Stock set to ${updatedStock} for SKU "${variantId}" at location ${effectiveLocationId}`,
      variantId,
      inventoryItemId,
      quantity: targetQty,
      updatedStock,
      locationId: effectiveLocationId,
      shopifyResponse: result
    }

  } catch (err: any) {
    const errData = err?.data || err
    const errMsg = errData?.message || errData?.errors || err?.message || 'Failed to sync stock to Shopify'
    const errStatus = err?.status || err?.response?.status || errData?.status || 500

    console.error('Shopify stock sync error:', {
      variantId,
      quantity,
      error: errData
    })

    return {
      status: errStatus,
      success: false,
      message: typeof errMsg === 'object' ? JSON.stringify(errMsg) : errMsg,
      error: errData,
      variantId
    }
  }
}

export default defineEventHandler(async (event) => {
  try {
    return await handleFunc(event)
  } catch (err: any) {
    try {
      const authToken = await refreshTokenHelper(event)
      return await handleFunc(event, authToken)
    } catch (error: any) {
      const data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      if([401, 402, 403, 407].includes(Number(data.status))) {
        //@ts-ignore
        setCookie(event, 'user', null)
      }
      return { ...data, success: false }
    }
  }
})
