namespace TaxBaik.Web.Services;

using System.Net.Http;
using System.Net.Http.Json;
using TaxBaik.Application.DTOs;
using TaxBaik.Domain.Entities;

/// <summary>
/// Inquiry API Client for Admin Blazor
/// SOLID: Single Responsibility - Inquiry API calls only
/// Dependency Inversion - abstraction via interface
/// </summary>
public interface IInquiryBrowserClient
{
    Task<(IEnumerable<Inquiry> Items, int Total)> GetPagedAsync(int page = 1, int pageSize = 20, CancellationToken ct = default);
    Task<Inquiry?> GetByIdAsync(int id, CancellationToken ct = default);
    Task<bool> UpdateStatusAsync(int id, string status, CancellationToken ct = default);
    Task<bool> UpdateAdminMemoAsync(int id, string adminMemo, CancellationToken ct = default);
    Task<Inquiry?> UpdateAsync(int id, UpdateInquiryDto dto, CancellationToken ct = default);
    Task<int> ConvertToClientAsync(int id, string name, string phone, string serviceType, CancellationToken ct = default);
    Task<Inquiry?> CreateAsync(SubmitInquiryDto dto, CancellationToken ct = default);
    Task<bool> DeleteAsync(int id, CancellationToken ct = default);
}

public class InquiryBrowserClient : IInquiryBrowserClient
{
    private readonly HttpClient _http;
    private readonly ILogger<InquiryBrowserClient> _logger;
    private readonly ITokenStore _tokenStore;

    public InquiryBrowserClient(HttpClient http, ILogger<InquiryBrowserClient> logger, ITokenStore tokenStore)
    {
        _http = http;
        _logger = logger;
        _tokenStore = tokenStore;
    }

    private void EnsureAuthHeader()
    {
        if (!string.IsNullOrEmpty(_tokenStore.AccessToken))
            _http.DefaultRequestHeaders.Authorization = new("Bearer", _tokenStore.AccessToken);
        else
            _http.DefaultRequestHeaders.Authorization = null;
    }

    public async Task<(IEnumerable<Inquiry> Items, int Total)> GetPagedAsync(
        int page = 1, int pageSize = 20, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var result = await _http.GetFromJsonAsync<InquiryPagedResponse>(
                $"inquiry?page={page}&pageSize={pageSize}",
                cancellationToken: ct);

            return result != null
                ? (result.Data, result.Total)
                : ([], 0);
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to fetch inquiries");
            throw;
        }
    }

    public async Task<Inquiry?> GetByIdAsync(int id, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            return await _http.GetFromJsonAsync<Inquiry>(
                $"inquiry/{id}",
                cancellationToken: ct);
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to fetch inquiry {InquiryId}", id);
            throw;
        }
    }

    public async Task<bool> UpdateStatusAsync(int id, string status, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var request = new { status };
            var response = await _http.PutAsJsonAsync(
                $"inquiry/{id}/status",
                request,
                cancellationToken: ct);

            return response.IsSuccessStatusCode;
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to update inquiry {InquiryId} status", id);
            throw;
        }
    }

    public async Task<bool> UpdateAdminMemoAsync(int id, string adminMemo, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var request = new { adminMemo };
            var response = await _http.PutAsJsonAsync(
                $"inquiry/{id}/memo",
                request,
                cancellationToken: ct);

            return response.IsSuccessStatusCode;
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to update inquiry {InquiryId} memo", id);
            throw;
        }
    }

    public async Task<Inquiry?> UpdateAsync(int id, UpdateInquiryDto dto, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var response = await _http.PutAsJsonAsync($"inquiry/{id}", dto, cancellationToken: ct);
            if (!response.IsSuccessStatusCode)
                return null;

            var content = await response.Content.ReadAsStringAsync(ct);
            return System.Text.Json.JsonSerializer.Deserialize<Inquiry>(
                content,
                new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to update inquiry {InquiryId}", id);
            throw;
        }
    }

    public async Task<int> ConvertToClientAsync(int id, string name, string phone, string serviceType, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var response = await _http.PostAsJsonAsync(
                $"inquiry/{id}/convert-to-client",
                new { name, phone, serviceType },
                cancellationToken: ct);

            if (!response.IsSuccessStatusCode)
                return 0;

            var content = await response.Content.ReadAsStringAsync(ct);
            var result = System.Text.Json.JsonSerializer.Deserialize<ConvertToClientResponse>(
                content,
                new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true });

            return result?.ClientId ?? 0;
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to convert inquiry {InquiryId} to client", id);
            throw;
        }
    }

    public async Task<Inquiry?> CreateAsync(SubmitInquiryDto dto, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var response = await _http.PostAsJsonAsync("inquiry", dto, cancellationToken: ct);
            if (!response.IsSuccessStatusCode)
                return null;

            var content = await response.Content.ReadAsStringAsync(ct);
            return System.Text.Json.JsonSerializer.Deserialize<Inquiry>(
                content,
                new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to create inquiry");
            throw;
        }
    }

    public async Task<bool> DeleteAsync(int id, CancellationToken ct = default)
    {
        try
        {
            EnsureAuthHeader();
            var response = await _http.DeleteAsync($"inquiry/{id}", ct);
            return response.IsSuccessStatusCode;
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, "Failed to delete inquiry {InquiryId}", id);
            throw;
        }
    }

    private class InquiryPagedResponse
    {
        public List<Inquiry> Data { get; set; } = [];
        public int Total { get; set; }
        public int Page { get; set; }
        public int PageSize { get; set; }
    }

    private class ConvertToClientResponse
    {
        public int ClientId { get; set; }
    }
}
