import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
import getTokenHelper from "../../../utils/getTokenHelper"

const handleFunc = async (event: any, authToken: any = null) => {
  let data: any = {
    status: 500,
    message: 'Sync failed',
    synced: 0,
    skipped: 0
  }

  try {
    const token = authToken ?? await getTokenHelper(event)
    const body = await readBody(event)
    const { sourceWarehouseId, targetWarehouseId } = body

    if(!sourceWarehouseId || !targetWarehouseId) {
      return {
        status: 400,
        message: 'Source and target warehouse IDs are required',
        synced: 0,
        skipped: 0
      }
    }

    if(sourceWarehouseId === targetWarehouseId) {
      return {
        status: 400,
        message: 'Source and target warehouses must be different',
        synced: 0,
        skipped: 0
      }
    }

    // Get source locators
    const sourceRes: any = await event.context.fetch(
      `models/m_locator?$filter=M_Warehouse_ID eq ${sourceWarehouseId}`,
      'GET',
      token,
      null
    )

    if(!sourceRes?.records || sourceRes.records.length === 0) {
      return {
        status: 404,
        message: 'No locators found in source warehouse',
        synced: 0,
        skipped: 0
      }
    }

    // Get existing target locators to check for duplicates
    const targetRes: any = await event.context.fetch(
      `models/m_locator?$filter=M_Warehouse_ID eq ${targetWarehouseId}`,
      'GET',
      token,
      null
    )

    const existingCoords = new Set()
    if(targetRes?.records) {
      targetRes.records.forEach((loc: any) => {
        const coordKey = `${loc.X}|${loc.Y}|${loc.Z}`
        existingCoords.add(coordKey)
      })
    }

    let synced = 0
    let skipped = 0

    // Sync each locator
    for(const sourceLoc of sourceRes.records) {
      const coordKey = `${sourceLoc.X}|${sourceLoc.Y}|${sourceLoc.Z}`

      // Skip if coordinates already exist in target
      if(existingCoords.has(coordKey)) {
        skipped++
        continue
      }

      // Create locator in target warehouse
      const createPayload = {
        M_Warehouse_ID: { id: targetWarehouseId },
        AD_Org_ID: { id: sourceLoc.AD_Org_ID?.id },
        X: sourceLoc.X,
        Y: sourceLoc.Y,
        Z: sourceLoc.Z,
        Value: sourceLoc.Value,
        PriorityNo: sourceLoc.PriorityNo || 50,
        IsActive: sourceLoc.IsActive ?? true,
        IsDefault: false
      }

      if(sourceLoc.M_LocatorType_ID?.id) {
        createPayload['M_LocatorType_ID'] = { id: sourceLoc.M_LocatorType_ID.id }
      }

      const createRes: any = await event.context.fetch(
        'models/m_locator',
        'POST',
        token,
        createPayload
      )

      if(createRes?.id) {
        synced++
        existingCoords.add(coordKey)
      } else {
        skipped++
      }
    }

    data = {
      status: 200,
      message: `Successfully synced ${synced} locators, ${skipped} skipped`,
      synced,
      skipped
    }
  } catch(err: any) {
    data = {
      status: err?.status || 500,
      message: err?.message || 'Error syncing locators',
      synced: 0,
      skipped: 0
    }
  }

  return data
}

export default defineEventHandler(async (event) => {
  let data: any = {}

  try {
    data = await handleFunc(event)
  } catch(err: any) {
    try {
      let authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch(error) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }

  return data
})
