using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using watcher_monitoring.Data;
using watcher_monitoring.Models;

namespace watcher_monitoring.Controllers;

[ApiController]
[Route("[controller]")]
public class ApiKeyController : Controller
{
    private readonly WatcherDbContext _context;
    private readonly ILogger<ApiKeyController> _logger;

    public ApiKeyController(WatcherDbContext context, ILogger<ApiKeyController> logger)
    {
        _context = context;
        _logger = logger;
    }

    // Generiert einen neuen API-Key
    private static string GenerateApiKey()
    {
        var randomBytes = new byte[32];
        using var rng = RandomNumberGenerator.Create();
        rng.GetBytes(randomBytes);
        return Convert.ToBase64String(randomBytes).Replace("+", "").Replace("/", "").Replace("=", "");
    }

    [HttpPost("create")]
    public async Task<IActionResult> CreateApiKey([FromBody] CreateApiKeyRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Name))
        {
            return BadRequest(new { error = "Name ist erforderlich" });
        }

        var apiKey = new ApiKey
        {
            Key = GenerateApiKey(),
            Name = request.Name,
            Description = request.Description,
            ExpiresAt = request.ExpiresAt,
            IsActive = true
        };

        _context.ApiKeys.Add(apiKey);
        await _context.SaveChangesAsync();

        _logger.LogInformation("Neuer API-Key erstellt: {Name}", apiKey.Name);

        return Ok(new
        {
            id = apiKey.Id,
            key = apiKey.Key, // Wird nur einmal zurückgegeben!
            name = apiKey.Name,
            description = apiKey.Description,
            createdAt = apiKey.CreatedAt,
            expiresAt = apiKey.ExpiresAt,
            isActive = apiKey.IsActive
        });
    }

    [HttpGet("list")]
    public async Task<IActionResult> ListApiKeys()
    {
        var apiKeys = await _context.ApiKeys
            .OrderByDescending(k => k.CreatedAt)
            .Select(k => new
            {
                id = k.Id,
                name = k.Name,
                description = k.Description,
                createdAt = k.CreatedAt,
                expiresAt = k.ExpiresAt,
                lastUsedAt = k.LastUsedAt,
                isActive = k.IsActive,
                isExpired = k.IsExpired,
                keyPreview = k.Key.Substring(0, Math.Min(8, k.Key.Length)) + "..." // Nur die ersten 8 Zeichen
            })
            .ToListAsync();

        return Ok(apiKeys);
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetApiKey(int id)
    {
        var apiKey = await _context.ApiKeys.FindAsync(id);

        if (apiKey == null)
        {
            return NotFound(new { error = "API-Key nicht gefunden" });
        }

        return Ok(new
        {
            id = apiKey.Id,
            name = apiKey.Name,
            description = apiKey.Description,
            createdAt = apiKey.CreatedAt,
            expiresAt = apiKey.ExpiresAt,
            lastUsedAt = apiKey.LastUsedAt,
            isActive = apiKey.IsActive,
            isExpired = apiKey.IsExpired,
            keyPreview = apiKey.Key.Substring(0, Math.Min(8, apiKey.Key.Length)) + "..."
        });
    }

    [HttpPut("{id}/toggle")]
    public async Task<IActionResult> ToggleApiKey(int id)
    {
        var apiKey = await _context.ApiKeys.FindAsync(id);

        if (apiKey == null)
        {
            return NotFound(new { error = "API-Key nicht gefunden" });
        }

        apiKey.IsActive = !apiKey.IsActive;
        await _context.SaveChangesAsync();

        _logger.LogInformation("API-Key {Name} wurde {Status}", apiKey.Name, apiKey.IsActive ? "aktiviert" : "deaktiviert");

        return Ok(new { isActive = apiKey.IsActive });
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteApiKey(int id)
    {
        var apiKey = await _context.ApiKeys.FindAsync(id);

        if (apiKey == null)
        {
            return NotFound(new { error = "API-Key nicht gefunden" });
        }

        _context.ApiKeys.Remove(apiKey);
        await _context.SaveChangesAsync();

        _logger.LogInformation("API-Key gelöscht: {Name}", apiKey.Name);

        return Ok(new { message = "API-Key erfolgreich gelöscht" });
    }
}

public class CreateApiKeyRequest
{
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public DateTime? ExpiresAt { get; set; }
}
