import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
import fetchHelper from "../../../utils/fetchHelper"
import { getAmazonAccessToken, resolveMarketplaceId, listFinancialEventGroupsSince } from "../../../utils/amazonSpApi"

// Default lookback when the caller doesn't set an explicit `createdSince` — a
// single ~100-day window covers ~7 biweekly settlement periods in one fast API
// call. An explicit `createdSince` reaches further back via chunked windowing
// inside listFinancialEventGroupsSince (Amazon's Finances API has no 90-day
// wall like the old Reports-API flow did).
const DEFAULT_LOOKBACK_DAYS = 100

// List the available Amazon settlement periods (Finances API financial event
// groups) for an order source — populates the period dropdown on the
// settlement-browser page. Unlike the old Reports-API-based
// GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE_V2 report listing (hard-capped by
// Amazon at a 90-day createdSince — verified against production:
// "RequestedFromDate ... is more than 90 days old"), this reaches back to the
// account's actual settlement history.
const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const query = getQuery(event)
  const orderSourceId = query.orderSourceId
  const createdSince = query.createdSince ? String(query.createdSince) : undefined
  const createdUntil = query.createdUntil ? String(query.createdUntil) : undefined

  if (!orderSourceId) {
    return { status: 400, message: 'orderSourceId is required' }
  }

  const orderSource: any = await fetchHelper(event, `models/c_ordersource/${orderSourceId}`, 'GET', token, null)
  if (!orderSource) {
    return { status: 404, message: 'Order source not found' }
  }

  const marketplaceIdentifier = String(orderSource?.Marketplace?.identifier || '').toLowerCase()
  const isAmazon = marketplaceIdentifier === 'amazon' || String(orderSource?.Marketplace?.id) === '4' || String(orderSource?.marketplace) === '4'
  if (!isAmazon) {
    return { status: 400, message: `Order source "${orderSource?.Name || orderSourceId}" is not an Amazon marketplace` }
  }

  if (!orderSource?.marketplace_key || !orderSource?.marketplace_secret || !orderSource?.marketplace_token) {
    return { status: 400, message: 'Order source is missing Amazon SP-API credentials (marketplace_key, marketplace_secret, marketplace_token)' }
  }

  // The Finances API isn't marketplace-scoped by parameter (unlike the old
  // Reports API call), but we still resolve+validate it here as an early,
  // clearer error for a misconfigured order source.
  if (!resolveMarketplaceId(orderSource?.Marketplace?.identifier, orderSource?.Description)) {
    return { status: 400, message: 'Could not resolve an Amazon marketplaceId from the order source' }
  }

  const accessToken = await getAmazonAccessToken(
    orderSource.marketplace_key,
    orderSource.marketplace_secret,
    orderSource.marketplace_token
  )

  const since = createdSince || new Date(Date.now() - DEFAULT_LOOKBACK_DAYS * 86400000).toISOString()
  const groups = await listFinancialEventGroupsSince(accessToken, since, createdUntil)

  return {
    status: 200,
    orderSourceId: Number(orderSourceId),
    // Field names kept close to the old Reports-API shape (reportId/dataStartTime/
    // dataEndTime) so the frontend needed only additive changes — reportId now
    // holds the Finances API's FinancialEventGroupId, not a Reports-API reportId.
    reports: groups.map(g => ({
      reportId: g.groupId,
      dataStartTime: g.periodStart,
      dataEndTime: g.periodEnd,
      totalAmount: g.totalAmount,
      currency: g.currency,
      fundTransferStatus: g.fundTransferStatus,
      fundTransferDate: g.fundTransferDate
    }))
  }
}

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

  try {
    data = await handleFunc(event)
  } catch (err: any) {
    // SP-API errors (e.g. missing Finance & Accounting role) carry a status —
    // surface them verbatim rather than treating them as an auth failure.
    if (err?.status && err?.message) {
      return { status: err.status, message: err.message, spapi: err.spapi }
    }
    try {
      let authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }

  return data
})
