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

const LWA_TOKEN_URL = 'https://api.amazon.com/auth/o2/token'
const SP_API_BASE_URL = 'https://sellingpartnerapi-eu.amazon.com'

// Test various SP-API endpoints to determine accessible resources
const testEndpoints = [
  { name: 'Feeds', path: '/feeds/2021-06-30/feeds?pageSize=1', description: 'Feeds API (list feeds)' },
  { name: 'Orders', path: '/orders/v0/orders?MarketplaceIds=A1PA6795UKMFR9&CreatedAfter=2099-01-01T00:00:00Z&MaxResultsPerPage=1', description: 'Orders API' },
  { name: 'Reports', path: '/reports/2021-06-30/reports?pageSize=1', description: 'Reports API' },
  { name: 'Catalog Items', path: '/catalog/2022-04-01/items?marketplaceIds=A1PA6795UKMFR9&keywords=test&pageSize=1', description: 'Catalog Items API' },
  { name: 'Sellers', path: '/sellers/v1/marketplaceParticipations', description: 'Sellers API (marketplace participations)' },
]

// Feed type access tests
const testFeedTypes = [
  { name: 'UPLOAD_VAT_INVOICE', feedType: 'UPLOAD_VAT_INVOICE', description: 'Tax Invoicing (Restricted) - required for invoice uploads' },
]

const handleFunc = async (event: any, authToken: any = null) => {
  const token = authToken ?? await getTokenHelper(event)
  const body = await readBody(event)
  const orderSourceId = body.orderSourceId

  if (!orderSourceId) {
    return { success: false, message: 'No order source ID provided' }
  }

  // Fetch order source credentials
  const orderSource: any = await fetchHelper(
    event,
    `models/c_ordersource/${orderSourceId}`,
    'GET',
    token,
    null
  )

  if (!orderSource) {
    return { success: false, message: 'Order source not found' }
  }

  const clientId = orderSource.marketplace_key
  const clientSecret = orderSource.marketplace_secret
  const refreshToken = orderSource.marketplace_token

  if (!clientId || !clientSecret || !refreshToken) {
    return {
      success: false,
      message: 'Missing Amazon SP-API credentials. Ensure Client ID (marketplace_key), Client Secret (marketplace_secret), and Refresh Token (marketplace_token) are set.',
      details: {
        hasClientId: !!clientId,
        hasClientSecret: !!clientSecret,
        hasRefreshToken: !!refreshToken,
      }
    }
  }

  // Step 1: Get LWA access token
  let accessToken: string
  try {
    const lwaResponse = await fetch(LWA_TOKEN_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'refresh_token',
        refresh_token: refreshToken,
        client_id: clientId,
        client_secret: clientSecret
      })
    })

    if (!lwaResponse.ok) {
      const errorText = await lwaResponse.text()
      return {
        success: false,
        message: `LWA authentication failed (${lwaResponse.status}): ${errorText}`,
        step: 'authentication'
      }
    }

    const lwaData: any = await lwaResponse.json()
    accessToken = lwaData.access_token
  } catch (err: any) {
    return {
      success: false,
      message: `LWA authentication error: ${err.message}`,
      step: 'authentication'
    }
  }

  // Step 2: Test marketplace participations (most basic endpoint)
  let marketplaces: any[] = []
  try {
    const sellersResponse = await fetch(`${SP_API_BASE_URL}/sellers/v1/marketplaceParticipations`, {
      method: 'GET',
      headers: {
        'x-amz-access-token': accessToken,
        'Content-Type': 'application/json'
      }
    })

    if (sellersResponse.ok) {
      const sellersData: any = await sellersResponse.json()
      marketplaces = sellersData.payload?.map((p: any) => ({
        marketplace: p.marketplace?.name || p.marketplace?.id,
        marketplaceId: p.marketplace?.id,
        country: p.marketplace?.countryCode,
        isParticipating: p.participation?.isParticipating,
      })) || []
    }
  } catch (err: any) {
    // Non-critical, continue testing
  }

  // Step 3: Test each endpoint for access
  const accessResults: any[] = []

  for (const endpoint of testEndpoints) {
    try {
      const response = await fetch(`${SP_API_BASE_URL}${endpoint.path}`, {
        method: 'GET',
        headers: {
          'x-amz-access-token': accessToken,
          'Content-Type': 'application/json'
        }
      })

      accessResults.push({
        name: endpoint.name,
        description: endpoint.description,
        status: response.status,
        accessible: response.ok,
        error: response.ok ? null : `${response.status} ${response.statusText}`
      })
    } catch (err: any) {
      accessResults.push({
        name: endpoint.name,
        description: endpoint.description,
        status: 0,
        accessible: false,
        error: err.message
      })
    }
  }

  // Step 4: Test feed type access by creating a dummy feed document
  const feedAccessResults: any[] = []

  for (const feedTest of testFeedTypes) {
    try {
      // Try to create a feed document (this tests basic feeds access)
      const docResponse = await fetch(`${SP_API_BASE_URL}/feeds/2021-06-30/documents`, {
        method: 'POST',
        headers: {
          'x-amz-access-token': accessToken,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ contentType: 'application/pdf' })
      })

      if (!docResponse.ok) {
        feedAccessResults.push({
          name: feedTest.name,
          description: feedTest.description,
          accessible: false,
          error: `Cannot create feed document: ${docResponse.status}`,
          step: 'createFeedDocument'
        })
        continue
      }

      const docData: any = await docResponse.json()

      // Now try to create the actual feed (this tests feed type permission)
      const feedResponse = await fetch(`${SP_API_BASE_URL}/feeds/2021-06-30/feeds`, {
        method: 'POST',
        headers: {
          'x-amz-access-token': accessToken,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          feedType: feedTest.feedType,
          marketplaceIds: ['A1PA6795UKMFR9'],
          inputFeedDocumentId: docData.feedDocumentId,
          feedOptions: {
            'metadata:orderid': '000-0000000-0000000',
            'metadata:invoicenumber': 'TEST-000',
            'metadata:documenttype': 'Invoice'
          }
        })
      })

      const feedResponseText = await feedResponse.text()
      let feedResponseData: any = {}
      try { feedResponseData = JSON.parse(feedResponseText) } catch (e) {}

      feedAccessResults.push({
        name: feedTest.name,
        description: feedTest.description,
        accessible: feedResponse.ok,
        status: feedResponse.status,
        error: feedResponse.ok ? null : (feedResponseData.errors?.[0]?.message || feedResponseText),
        feedId: feedResponseData.feedId || null,
        step: 'createFeed'
      })
    } catch (err: any) {
      feedAccessResults.push({
        name: feedTest.name,
        description: feedTest.description,
        accessible: false,
        error: err.message,
        step: 'error'
      })
    }
  }

  const allEndpointsAccessible = accessResults.every(r => r.accessible)
  const feedsAccessible = feedAccessResults.every(r => r.accessible)
  const hasInvoiceUploadAccess = feedAccessResults.find(r => r.name === 'UPLOAD_VAT_INVOICE')?.accessible || false

  let statusMessage = 'Amazon SP-API connection successful.'
  if (!hasInvoiceUploadAccess) {
    const feedError = feedAccessResults.find(r => r.name === 'UPLOAD_VAT_INVOICE')
    statusMessage = `Connection works but UPLOAD_VAT_INVOICE feed access is DENIED (${feedError?.status || 'unknown'}). Your app needs the "Tax Invoicing (Restricted)" role. Go to Amazon Seller Central > Developer Profile > Edit App > add the "Tax Invoicing" restricted role.`
  }

  return {
    success: true,
    message: statusMessage,
    authentication: 'OK',
    marketplaces,
    apiAccess: accessResults,
    feedAccess: feedAccessResults,
    hasInvoiceUploadAccess,
    summary: {
      authenticated: true,
      marketplaceCount: marketplaces.length,
      accessibleApis: accessResults.filter(r => r.accessible).map(r => r.name),
      deniedApis: accessResults.filter(r => !r.accessible).map(r => `${r.name} (${r.error})`),
      invoiceUploadReady: hasInvoiceUploadAccess,
    }
  }
}

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
})
