Imports Newtonsoft.Json
Imports Newtonsoft.Json.Converters
Imports Newtonsoft.Json.Serialization

Public Class TamiPagoManager
    Private ReadOnly _httpClient As TamiHttpClient
    Private ReadOnly _secretKey As String
    Private ReadOnly _merchantId As Long
    Private ReadOnly _terminalId As Long
    Private ReadOnly _fixedKidValue As String
    Private ReadOnly _fixedKValue As String
    Public Sub New(baseAddress As String, merchantId As Long, terminalId As Long, secretKey As String, fixedKidValue As String, fixedKValue As String)
        _merchantId = merchantId
        _terminalId = terminalId
        _secretKey = secretKey
        _fixedKidValue = fixedKidValue
        _fixedKValue = fixedKValue
        _httpClient = New TamiHttpClient(baseAddress, merchantId, terminalId, secretKey)
    End Sub

    Public Sub New(httpClient As TamiHttpClient)
        _httpClient = httpClient
        _secretKey = httpClient._secretKey
    End Sub

    Public Async Function AuthAsync(request As AuthRequest) As Task(Of AuthResponse)
        Return Await PostRequestAsync(Of AuthRequest, AuthResponse)("payment/auth", request)
    End Function

    Public Async Function AuthWithBonusAsync(request As AuthWithBonusRequest) As Task(Of AuthWithBonusResponse)
        Return Await PostRequestAsync(Of AuthWithBonusRequest, AuthWithBonusResponse)("payment/auth", request)
    End Function

    Public Async Function PreAuthAsync(request As PreAuthRequest) As Task(Of PreAuthResponse)
        Return Await PostRequestAsync(Of PreAuthRequest, PreAuthResponse)("payment/pre-auth", request)
    End Function

    Public Async Function PostAuthAsync(request As PostAuthRequest) As Task(Of PostAuthResponse)
        Return Await PostRequestAsync(Of PostAuthRequest, PostAuthResponse)("payment/post-auth", request)
    End Function

    Public Async Function ReverseAsync(request As ReverseRequest) As Task(Of ReverseResponse)
        Return Await PostRequestAsync(Of ReverseRequest, ReverseResponse)("payment/reverse", request)
    End Function

    Public Async Function Complete3DAuthAsync(request As Complete3dAuthRequest) As Task(Of Complete3dAuthResponse)
        Return Await PostRequestAsync(Of Complete3dAuthRequest, Complete3dAuthResponse)("payment/complete-3ds", request)
    End Function

    Public Async Function Auth3DAsync(request As ThreeDAuthRequest) As Task(Of ThreeDAuthResponse)
        Return Await PostRequestAsync(Of ThreeDAuthRequest, ThreeDAuthResponse)("payment/auth", request)
    End Function

    Public Async Function PreAuth3DAsync(request As ThreeDPreAuthRequest) As Task(Of ThreeDPreAuthResponse)
        Return Await PostRequestAsync(Of ThreeDPreAuthRequest, ThreeDPreAuthResponse)("payment/pre-auth", request)
    End Function

    Public Async Function QueryAsync(request As QueryRequest) As Task(Of QueryResponse)
        Return Await PostRequestAsync(Of QueryRequest, QueryResponse)("payment/query", request)
    End Function

    Public Async Function InstallmentInfoAsync(request As InstallmentInfoRequest) As Task(Of InstallmentInfoResponse)
        Return Await PostRequestAsync(Of InstallmentInfoRequest, InstallmentInfoResponse)("installment/installment-info", request)
    End Function

    Public Async Function BINInfoAsync(request As BinInfoRequest) As Task(Of BinInfoResponse)
        Return Await PostRequestAsync(Of BinInfoRequest, BinInfoResponse)("installment/bin-info", request)
    End Function

    Public Async Function BonusInquiryAsync(request As BonusInquiryRequest) As Task(Of BonusInquiryResponse)
        Return Await PostRequestAsync(Of BonusInquiryRequest, BonusInquiryResponse)("vas/bonusQuery", request)
    End Function


    Private Async Function PostRequestAsync(Of T As {RequestBase}, Y As {ResponseBase})(path As String, request As T) As Task(Of Y)
        Dim requestValidation = request.Validate()

        If requestValidation.Succeeded Then
            Dim requestObject As String = JsonConvert.SerializeObject(request, New JsonSerializerSettings() With {
                .Converters = {New IsoDateTimeConverter With {.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fff"}},
                .NullValueHandling = NullValueHandling.Ignore,
                .ContractResolver = New CamelCasePropertyNamesContractResolver()
            })

            request.SecurityHash = CryptoHelper.GenerateJWKSignature(_fixedKidValue, _fixedKValue, requestObject)

            Return Await _httpClient.PostAsync(Of Y)(path, request)
        End If
        Throw New Exception($"İstek validasyon hatası: {String.Join(",", requestValidation.Errors)}")
    End Function
End Class