' =============================================
' Repsly API Client
' Created: 2025-01-XX
' Purpose: Handle HTTP requests to Repsly API
'          Supports GET, POST operations with Basic Authentication
' =============================================

Imports System.Net.Http
Imports System.Text
Imports System.Threading.Tasks
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports Superbowl_Daily_2.ProjectFunctions
Imports Superbowl_Daily_2.SystemFunctions

Public Class RepslyAPIClient

    Private ReadOnly baseUrl As String
    Private ReadOnly username As String
    Private ReadOnly password As String
    Private ReadOnly httpClient As HttpClient
    Private ReadOnly processName As String

    ' =============================================
    ' Constructor
    ' =============================================
    Public Sub New(Optional processName As String = "Repsly API")
        Me.baseUrl = My.Settings.RepslyAPIBaseUrl
        Me.username = My.Settings.RepslyAPIUsername
        Me.password = My.Settings.RepslyAPIPassword
        Me.processName = processName

        ' Initialize HTTP client with Basic Auth
        Me.httpClient = New HttpClient()
        Me.httpClient.Timeout = TimeSpan.FromSeconds(60) ' 60 second timeout
        Me.httpClient.DefaultRequestHeaders.Add("Accept", "application/json")
        
        ' Set Basic Authentication
        Dim authValue As String = Convert.ToBase64String(Encoding.UTF8.GetBytes(username & ":" & password))
        Me.httpClient.DefaultRequestHeaders.Authorization = New System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authValue)
    End Sub

    ' =============================================
    ' GET Request - Export data from Repsly
    ' =============================================
    Public Function GetAsync(endpoint As String) As String
        Try
            Dim url As String = baseUrl & endpoint
            WriteLog("info", processName, "API GET Request", "Requesting: " & url)

            Dim response As HttpResponseMessage = httpClient.GetAsync(url).Result
            Dim responseBody As String = response.Content.ReadAsStringAsync().Result

            If response.IsSuccessStatusCode Then
                WriteLog("info", processName, "API GET Response", "Success: " & response.StatusCode.ToString())
                Return responseBody
            Else
                WriteLog("error", processName, "API GET Error", "Status: " & response.StatusCode.ToString() & " | Response: " & responseBody)
                Throw New HttpRequestException("API request failed: " & response.StatusCode.ToString() & " - " & responseBody)
            End If

        Catch ex As Exception
            WriteLog("error", processName, "API GET Exception", ex.Message & " :: " & ex.StackTrace)
            Throw
        End Try
    End Function

    ' =============================================
    ' POST Request - Import data to Repsly
    ' =============================================
    Public Function PostAsync(endpoint As String, jsonData As String) As RepslyAPIResponse
        Try
            Dim url As String = baseUrl & endpoint
            WriteLog("info", processName, "API POST Request", "Posting to: " & url)

            Dim content As New StringContent(jsonData, Encoding.UTF8, "application/json")
            Dim response As HttpResponseMessage = httpClient.PostAsync(url, content).Result
            Dim responseBody As String = response.Content.ReadAsStringAsync().Result

            If response.IsSuccessStatusCode Then
                WriteLog("info", processName, "API POST Response", "Success: " & response.StatusCode.ToString() & " | Response: " & responseBody)
                
                ' Parse response
                Dim apiResponse As RepslyAPIResponse = JsonConvert.DeserializeObject(Of RepslyAPIResponse)(responseBody)
                Return apiResponse
            Else
                WriteLog("error", processName, "API POST Error", "Status: " & response.StatusCode.ToString() & " | Response: " & responseBody)
                
                ' Try to parse error response
                Dim apiResponse As New RepslyAPIResponse()
                Try
                    apiResponse = JsonConvert.DeserializeObject(Of RepslyAPIResponse)(responseBody)
                Catch
                    apiResponse.Code = -1
                    apiResponse.Message = "HTTP Error: " & response.StatusCode.ToString() & " - " & responseBody
                End Try
                Return apiResponse
            End If

        Catch ex As Exception
            WriteLog("error", processName, "API POST Exception", ex.Message & " :: " & ex.StackTrace)
            Dim errorResponse As New RepslyAPIResponse()
            errorResponse.Code = -1
            errorResponse.Message = "Exception: " & ex.Message
            Return errorResponse
        End Try
    End Function

    ' =============================================
    ' Get Import Job Status
    ' =============================================
    Public Function GetImportStatus(importJobID As String) As RepslyImportStatus
        Try
            Dim endpoint As String = "/export/importStatus/" & importJobID
            Dim responseBody As String = GetAsync(endpoint)
            
            Dim status As RepslyImportStatus = JsonConvert.DeserializeObject(Of RepslyImportStatus)(responseBody)
            Return status

        Catch ex As Exception
            WriteLog("error", processName, "Get Import Status Exception", ex.Message & " :: " & ex.StackTrace)
            Return Nothing
        End Try
    End Function

    ' =============================================
    ' Dispose
    ' =============================================
    Public Sub Dispose()
        If httpClient IsNot Nothing Then
            httpClient.Dispose()
        End If
    End Sub

End Class

' =============================================
' Response Classes
' =============================================

Public Class RepslyAPIResponse
    Public Property Code As Integer
    Public Property Message As String
End Class

Public Class RepslyImportStatus
    Public Property ImportStatus As String ' "Completed", "Failed", "Pending"
    Public Property RowsInserted As Integer
    Public Property RowsUpdated As Integer
    Public Property RowsInvalid As Integer
    Public Property RowsTotal As Integer
    Public Property Warnings As List(Of RepslyImportWarning)
    Public Property Errors As List(Of RepslyImportError)
End Class

Public Class RepslyImportWarning
    Public Property ItemID As String
    Public Property ItemName As String
    Public Property ItemStatus As String
End Class

Public Class RepslyImportError
    Public Property ItemID As String
    Public Property ItemName As String
    Public Property ItemStatus As String
End Class

