// EN: Strategy for Service products.
// VI: Strategy cho sản phẩm Service.

using OrderService.Domain.AggregatesModel.OrderAggregate;
using OrderService.Domain.Strategies;
using OrderService.API.Infrastructure.HttpClients;
using System.Text.Json;

namespace OrderService.API.Application.Strategies;

/// <summary>
/// EN: Strategy for Service products - routes to Booking Service.
/// VI: Strategy cho sản phẩm Service - route đến Booking Service.
/// </summary>
public class ServiceStrategy : ILineItemStrategy
{
    private readonly BookingServiceClient _bookingClient;
    private readonly ILogger<ServiceStrategy> _logger;

    public string SupportedType => "Service";

    public ServiceStrategy(
        BookingServiceClient bookingClient,
        ILogger<ServiceStrategy> logger)
    {
        _bookingClient = bookingClient ?? throw new ArgumentNullException(nameof(bookingClient));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<bool> ValidateAsync(
        OrderItem item,
        Guid shopId,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "EN: Validating Service product / VI: Validate sản phẩm Service: {ProductName}",
            item.ProductName);

        // EN: Parse metadata for appointment details
        // VI: Parse metadata cho chi tiết đặt lịch
        var metadata = ParseMetadata(item.Metadata);
        if (metadata == null)
        {
            _logger.LogWarning("EN: Invalid metadata for Service item / VI: Metadata không hợp lệ cho Service item");
            return false;
        }

        // EN: Check availability
        // VI: Kiểm tra lịch trống
        var isAvailable = await _bookingClient.CheckAvailabilityAsync(
            item.ProductId,
            shopId,
            metadata.StartTime,
            metadata.DurationMinutes,
            cancellationToken);

        if (!isAvailable)
        {
            _logger.LogWarning(
                "EN: Time slot not available / VI: Lịch không trống: {ProductName}, Time: {StartTime}",
                item.ProductName,
                metadata.StartTime);
        }

        return isAvailable;
    }

    public async Task ExecuteAsync(
        OrderItem item,
        Guid shopId,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "EN: Executing Service product / VI: Thực thi sản phẩm Service: {ProductName}",
            item.ProductName);

        // EN: Parse metadata
        // VI: Parse metadata
        var metadata = ParseMetadata(item.Metadata);
        if (metadata == null)
        {
            throw new InvalidOperationException("EN: Invalid metadata / VI: Metadata không hợp lệ");
        }

        // EN: Create appointment
        // VI: Tạo đặt lịch
        var appointmentId = await _bookingClient.CreateAppointmentAsync(
            item.ProductId,
            shopId,
            null, // Customer ID can be null for walk-in
            metadata.StartTime,
            metadata.DurationMinutes,
            cancellationToken);

        if (appointmentId == null)
        {
            throw new InvalidOperationException(
                $"EN: Failed to create appointment / VI: Tạo đặt lịch thất bại: {item.ProductName}");
        }

        _logger.LogInformation(
            "EN: Appointment created / VI: Đặt lịch thành công: {ProductName}, AppointmentId: {AppointmentId}",
            item.ProductName,
            appointmentId);
    }

    private ServiceMetadata? ParseMetadata(string? metadataJson)
    {
        if (string.IsNullOrEmpty(metadataJson))
        {
            return null;
        }

        try
        {
            return JsonSerializer.Deserialize<ServiceMetadata>(metadataJson);
        }
        catch
        {
            return null;
        }
    }
}

/// <summary>
/// EN: Metadata for Service items.
/// VI: Metadata cho Service items.
/// </summary>
public record ServiceMetadata(
    DateTime StartTime,
    int DurationMinutes
);
