Imports System.Configuration
Imports System.Diagnostics
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Threading.Tasks
Imports Newtonsoft.Json

Public Class TsNotificacionesClient

    Private ReadOnly _http As HttpClient
    Private ReadOnly _idAplicacion As Integer

    Public Sub New(baseUrl As String, idAplicacion As Integer, apiKey As String)
        _idAplicacion = idAplicacion

        ServicePointManager.ServerCertificateValidationCallback = Function(s, c, ch, e) True
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11

        _http = New HttpClient() With {.BaseAddress = New Uri(baseUrl)}
        _http.DefaultRequestHeaders.Add("X-Api-Key", apiKey)
    End Sub

    Public Shared Async Function RegistrarAsync(titulo As String, descripcion As String, tipo As TipoNotificacionEnum, Optional fichero As Byte() = Nothing, Optional incluirEnEventLog As Boolean = True) As Task
        Try
            ' ============================
            '   CARGAR CONFIGURACIÓN
            ' ============================
            Dim apiUrl As String = ConfigurationManager.AppSettings("TsNotificaciones.ApiUrl")
            Dim idAplicacion As Integer = Integer.Parse(ConfigurationManager.AppSettings("TsNotificaciones.IdAplicacion"))
            Dim aplicacion As String = ConfigurationManager.AppSettings("TsNotificaciones.Aplicacion")
            If aplicacion = "" Then aplicacion = "Tecnosis idAplicacion:" & idAplicacion.ToString
            Dim apiKey As String = ConfigurationManager.AppSettings("TsNotificaciones.ApiKey")
            Dim nombreServidor As String = Environment.MachineName

            If String.IsNullOrEmpty(apiUrl) Then apiUrl = "http://localhost:7159"

            ' ============================
            '   LOG EN EVENT VIEWER
            ' ============================
            If incluirEnEventLog Then
                Dim ele As EventLogEntryType

                Select Case tipo
                    Case TipoNotificacionEnum.INFO
                        ele = EventLogEntryType.Information
                    Case TipoNotificacionEnum.ADVERTENCIA
                        ele = EventLogEntryType.Warning
                    Case TipoNotificacionEnum.ERROR, TipoNotificacionEnum.CRÍTICO
                        ele = EventLogEntryType.Error
                End Select

                ' EventID ≠ 0 para evitar el mensaje de descripción faltante
                Dim eventId As Integer = 1000 + CInt(tipo)

                EventLog.WriteEntry("Application", $"{aplicacion} {titulo} {descripcion}", ele, eventId)
            End If

            ' ============================
            '   LLAMADA A LA API
            ' ============================
            Dim http = New HttpClient() With {.BaseAddress = New Uri(apiUrl)}
            http.DefaultRequestHeaders.Add("X-Api-Key", apiKey)

            Dim payload = New With {
                .idAplicacion = idAplicacion,
                .nombreServidor = nombreServidor,
                .ipServidor = ObtenerIp(),
                .titulo = titulo,
                .descripcion = descripcion,
                .tipoNotificacion = CInt(tipo)
            }

            Dim json As String = JsonConvert.SerializeObject(payload)
            Dim content As New StringContent(json, System.Text.Encoding.UTF8, "application/json")

            Dim response = Await http.PostAsync("/api/alertas/registrar", content)
            Dim body As String = Await response.Content.ReadAsStringAsync()

            Dim jsonObj = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(body)
            Dim id As Integer = Convert.ToInt32(jsonObj("id"))

            If fichero IsNot Nothing Then
                Await SubirFichero(http, apiKey, id, fichero)
            End If

        Catch ex As Exception
            Throw New Exception(ex.Message, ex)
        End Try
    End Function

    Private Shared Async Function SubirFichero(http As HttpClient, apiKey As String, alertaId As Integer, datos As Byte()) As Task
        Try
            Dim fileContent = New ByteArrayContent(datos)
            fileContent.Headers.ContentType = New MediaTypeHeaderValue("image/png")

            Dim multipart = New MultipartFormDataContent()
            multipart.Add(fileContent, "archivo", "Imagen.png")

            Dim request = New HttpRequestMessage(HttpMethod.Post, $"/api/alertas/{alertaId}/archivo")
            request.Headers.Add("X-Api-Key", apiKey)
            request.Content = multipart

            Dim response = Await http.SendAsync(request)

            If Not response.IsSuccessStatusCode Then
                Throw New Exception($"Subida fallida ({response.StatusCode}): {Await response.Content.ReadAsStringAsync()}")
            End If

        Catch ex As Exception
            Throw New Exception(ex.Message, ex)
        End Try
    End Function

    Private Shared Function ObtenerIp() As String
        For Each addr In Dns.GetHostAddresses(Dns.GetHostName())
            If addr.AddressFamily = Sockets.AddressFamily.InterNetwork Then Return addr.ToString()
        Next
        Return "127.0.0.1"
    End Function

    Public Enum TipoNotificacionEnum
        INFO = 0
        ADVERTENCIA = 1
        [ERROR] = 2
        CRÍTICO = 3
    End Enum

End Class
