using DbController;
using Microsoft.AspNetCore.Http;
using Tabletop.Core.Models;

namespace Tabletop.Core.Services
{
    public class ConnectionLogService(GeolocationService geolocationService)
    {
        private readonly GeolocationService _geolocationService = geolocationService;

        public static async Task CreateAsync(ConnectionLog input, IDbController dbController, CancellationToken cancellationToken = default)
        {
            // SQL-Insert-Statement für das ConnectionLog
            string sql = $@"
            INSERT INTO ConnectionLogs
            (
                IpAddress,
                ConnectionTime,
                UserAgent,
                Referrer,
                RequestedUrl,
                Geolocation,
                SessionId,
                StatusCode,
                DeviceType,
                OperatingSystem
            )
            VALUES
            (
                @IP_ADDRESS,
                @CONNECTION_TIME,
                @USER_AGENT,
                @REFERRER,
                @REQUESTED_URL,
                @GEOLOCATION,
                @SESSION_ID,
                @STATUS_CODE,
                @DEVICE_TYPE,
                @OPERATING_SYSTEM
            ); {dbController.GetLastIdSql()}";



            await dbController.QueryAsync(sql, input.GetParameters(), cancellationToken);
        }

        public async Task<ConnectionLog> GetConnectionLogAsync(HttpContext context)
        {
            // Extrahiere die IP-Adresse
            var ipAddress = context.Connection.RemoteIpAddress?.ToString() ?? "Unknown";

            // Hole die Geolocation (Stadt, Land, Koordinaten etc.) basierend auf der IP-Adresse
            var geolocation = await _geolocationService.GetGeolocationAsync(ipAddress);

            // Extrahiere den User-Agent-Header aus dem HttpContext
            var userAgent = context.Request.Headers["User-Agent"].FirstOrDefault() ?? "Unknown";

            // Bestimmung des DeviceTypes und des Betriebssystems
            var deviceType = await GetDeviceType(userAgent);
            var operatingSystem = await GetOperatingSystem(userAgent);

            // Erstelle das ConnectionLog
            return new ConnectionLog
            {
                IpAddress = ipAddress,
                ConnectionTime = DateTime.UtcNow,
                UserAgent = userAgent,
                Referrer = context.Request.Headers["Referer"].FirstOrDefault() ?? "Unknown",
                RequestedUrl = context.Request.Path,
                Geolocation = geolocation,  // Füge die Geolocation hinzu
                SessionId = context.Session?.Id ?? Guid.NewGuid().ToString(),
                StatusCode = context.Response.StatusCode,
                DeviceType = deviceType,
                OperatingSystem = operatingSystem
            };
        }

        // Methode zur Bestimmung des Device-Typs anhand des User-Agent-Strings
        public static Task<string> GetDeviceType(string userAgent)
        {
            string deviceType;

            if (userAgent.Contains("Mobi") || userAgent.Contains("Android") || userAgent.Contains("iPhone") || userAgent.Contains("iPad"))
            {
                deviceType = "Mobile";
            }
            else if (userAgent.Contains("Tablet") || userAgent.Contains("iPad"))
            {
                deviceType = "Tablet";
            }
            else
            {
                deviceType = "Desktop";  // Default ist Desktop
            }

            return Task.FromResult(deviceType);  // Verpackt den Wert in einem Task
        }

        // Methode zur Bestimmung des Betriebssystems anhand des User-Agent-Strings
        public static Task<string> GetOperatingSystem(string userAgent)
        {
            string operatingSystem;

            if (userAgent.Contains("Windows"))
            {
                operatingSystem = "Windows";
            }
            else if (userAgent.Contains("Mac OS"))
            {
                operatingSystem = "macOS";
            }
            else if (userAgent.Contains("Linux"))
            {
                operatingSystem = "Linux";
            }
            else if (userAgent.Contains("Android"))
            {
                operatingSystem = "Android";
            }
            else if (userAgent.Contains("iPhone") || userAgent.Contains("iPad"))
            {
                operatingSystem = "iOS";
            }
            else
            {
                operatingSystem = "Other";  // Default: Unbekanntes Betriebssystem
            }

            return Task.FromResult(operatingSystem);  // Verpackt den Wert in einem Task
        }
    }
}