using Microsoft.AspNetCore.Mvc;
using BTCPayServer.Client;
using BTCPayServer.Client.Models;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json.Linq;
using LittleShop.Services;
using LittleShop.Enums;

namespace LittleShop.Controllers;

[ApiController]
[Route("api/btcpay-test")]
[Authorize(AuthenticationSchemes = "Cookies", Roles = "Admin")]
public class BTCPayTestController : ControllerBase
{
    private readonly IConfiguration _configuration;
    private readonly IBTCPayServerService _btcPayService;
    private readonly ILogger<BTCPayTestController> _logger;

    public BTCPayTestController(
        IConfiguration configuration,
        IBTCPayServerService btcPayService,
        ILogger<BTCPayTestController> logger)
    {
        _configuration = configuration;
        _btcPayService = btcPayService;
        _logger = logger;
    }

    [HttpGet("connection")]
    public async Task<IActionResult> TestConnection()
    {
        try
        {
            var baseUrl = _configuration["BTCPayServer:BaseUrl"];
            var apiKey = _configuration["BTCPayServer:ApiKey"];
            
            if (string.IsNullOrEmpty(baseUrl) || string.IsNullOrEmpty(apiKey))
            {
                return BadRequest(new { error = "BTCPay Server configuration missing" });
            }

            // Create HttpClient with certificate bypass for internal networks
            var httpClient = new HttpClient(new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
            });
            
            var client = new BTCPayServerClient(new Uri(baseUrl), apiKey, httpClient);
            
            // Test basic connection by getting server info
            var serverInfo = await client.GetServerInfo();
            
            return Ok(new 
            { 
                status = "Connected",
                baseUrl = baseUrl,
                serverVersion = serverInfo?.Version,
                supportedPaymentMethods = serverInfo?.SupportedPaymentMethods,
                message = "BTCPay Server connection successful"
            });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new 
            { 
                error = ex.Message,
                type = ex.GetType().Name,
                baseUrl = _configuration["BTCPayServer:BaseUrl"]
            });
        }
    }

    [HttpGet("stores")]
    public async Task<IActionResult> GetStores()
    {
        try
        {
            var baseUrl = _configuration["BTCPayServer:BaseUrl"];
            var apiKey = _configuration["BTCPayServer:ApiKey"];
            
            // Create HttpClient with certificate bypass for internal networks
            var httpClient = new HttpClient(new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
            });
            
            var client = new BTCPayServerClient(new Uri(baseUrl), apiKey, httpClient);
            
            // Get available stores
            var stores = await client.GetStores();
            
            return Ok(new 
            { 
                stores = stores.Select(s => new 
                {
                    id = s.Id,
                    name = s.Name,
                    website = s.Website,
                    defaultCurrency = s.DefaultCurrency
                }).ToList(),
                message = "Stores retrieved successfully"
            });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new 
            { 
                error = ex.Message,
                type = ex.GetType().Name
            });
        }
    }

    [HttpGet("invoice/{invoiceId}")]
    public async Task<IActionResult> GetInvoiceDetails(string invoiceId)
    {
        try
        {
            var invoice = await _btcPayService.GetInvoiceAsync(invoiceId);

            if (invoice == null)
            {
                return NotFound(new { error = "Invoice not found" });
            }

            // BTCPay Server v2 manages addresses internally
            // Customers use the CheckoutLink for payments
            var paymentInfo = new
            {
                checkoutMethod = "BTCPay Checkout",
                info = "Use the checkout link to complete payment"
            };

            return Ok(new
            {
                invoiceId = invoice.Id,
                status = invoice.Status,
                amount = invoice.Amount,
                currency = invoice.Currency,
                checkoutLink = invoice.CheckoutLink,
                expiresAt = invoice.ExpirationTime,
                paymentMethods = paymentInfo,
                metadata = invoice.Metadata,
                message = "Invoice details retrieved successfully"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get invoice {InvoiceId}", invoiceId);
            return StatusCode(500, new
            {
                error = ex.Message,
                type = ex.GetType().Name
            });
        }
    }

    [HttpPost("test-invoice")]
    public async Task<IActionResult> CreateTestInvoice([FromBody] TestInvoiceRequest request)
    {
        try
        {
            var baseUrl = _configuration["BTCPayServer:BaseUrl"];
            var apiKey = _configuration["BTCPayServer:ApiKey"];
            var storeId = _configuration["BTCPayServer:StoreId"];
            
            if (string.IsNullOrEmpty(storeId))
            {
                return BadRequest(new { error = "Store ID not configured" });
            }

            // Create HttpClient with certificate bypass for internal networks
            var httpClient = new HttpClient(new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
            });
            
            var client = new BTCPayServerClient(new Uri(baseUrl), apiKey, httpClient);
            
            // Create test invoice
            var invoiceRequest = new CreateInvoiceRequest
            {
                Amount = request.Amount,
                Currency = request.Currency ?? "GBP",
                Metadata = JObject.FromObject(new 
                {
                    orderId = $"test-{Guid.NewGuid()}",
                    source = "LittleShop-Test"
                })
            };

            var invoice = await client.CreateInvoice(storeId, invoiceRequest);
            
            return Ok(new 
            { 
                status = "Invoice Created",
                invoiceId = invoice.Id,
                amount = invoice.Amount,
                currency = invoice.Currency,
                checkoutLink = invoice.CheckoutLink,
                expiresAt = invoice.ExpirationTime,
                message = "Test invoice created successfully"
            });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new 
            { 
                error = ex.Message,
                type = ex.GetType().Name
            });
        }
    }

    [HttpPost("test-payment")]
    public async Task<IActionResult> CreateTestPayment([FromBody] TestPaymentRequest request)
    {
        try
        {
            // Create a test order ID
            var testOrderId = $"test-order-{Guid.NewGuid():N}".Substring(0, 20);

            _logger.LogInformation("Creating test payment for {Currency} with amount {Amount} GBP",
                request.CryptoCurrency, request.Amount);

            // Use the actual service to create an invoice
            var invoiceId = await _btcPayService.CreateInvoiceAsync(
                request.Amount,
                request.CryptoCurrency,
                testOrderId,
                "Test payment from BTCPay diagnostic endpoint"
            );

            // Get the invoice details
            var invoice = await _btcPayService.GetInvoiceAsync(invoiceId);

            // BTCPay Server v2 uses checkout links instead of exposing raw addresses
            var checkoutUrl = invoice?.CheckoutLink;

            return Ok(new
            {
                status = "Success",
                invoiceId = invoiceId,
                orderId = testOrderId,
                amount = request.Amount,
                currency = "GBP",
                requestedCrypto = request.CryptoCurrency.ToString(),
                checkoutLink = checkoutUrl,
                paymentUrl = checkoutUrl ?? $"https://{_configuration["BTCPayServer:BaseUrl"]}/i/{invoiceId}",
                message = !string.IsNullOrEmpty(checkoutUrl)
                    ? "✅ Test payment created successfully - Use checkout link to complete payment"
                    : "⚠️ Invoice created but checkout link not available - Check BTCPay configuration"
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to create test payment");
            return StatusCode(500, new
            {
                error = ex.Message,
                type = ex.GetType().Name,
                hint = "Check that BTCPay Server has wallets configured for the requested currency"
            });
        }
    }
}

public class TestInvoiceRequest
{
    public decimal Amount { get; set; } = 0.01m;
    public string? Currency { get; set; } = "GBP";
}

public class TestPaymentRequest
{
    public decimal Amount { get; set; } = 10.00m;
    public CryptoCurrency CryptoCurrency { get; set; } = CryptoCurrency.BTC;
}