using DoliMiddlewareApi.Dtos.command;
using DoliMiddlewareApi.Dtos.Dolibarr;
using DoliMiddlewareApi.Dtos.query;
using DoliMiddlewareApi.Exceptions;
using DoliMiddlewareApi.Mappers;
using DoliMiddlewareApi.Services.Clients;

namespace DoliMiddlewareApi.Services;

public class ContactService(IDolibarrApiClient apiClient)
{
    public async Task<List<ContactDto>> GetContactsAsync(int limit = 50, int page = 1, string? thirdpartyIds = null)
    {
        var endpoint = $"contacts?limit={limit}&page={page - 1}";
        if (!string.IsNullOrEmpty(thirdpartyIds))
            endpoint += $"&thirdparty_ids={thirdpartyIds}";

        var data = await apiClient.GetCollectionAsync<ContactResponse>(endpoint);
        return data.Select(ContactMapper.MapToContactDto).ToList();
    }

    public async Task<ContactDetailDto> GetContactAsync(int id)
    {
        var data = await apiClient.GetResourceAsync<ContactResponse>($"contacts/{id}");
        return ContactMapper.MapToContactDetailDto(data);
    }

    public async Task<ContactDetailDto> GetContactByEmailAsync(string email)
    {
        var data = await apiClient.GetCollectionAsync<ContactResponse>(
            $"contacts/email/{Uri.EscapeDataString(email)}");

        if (data.Count == 0)
            throw new NotFoundException($"Contact with email '{email}' not found");

        return ContactMapper.MapToContactDetailDto(data[0]);
    }

    public async Task<int> CreateContactAsync(CreateContactDto dto)
    {
        var requestBody = new Dictionary<string, object?>
        {
            ["lastname"] = dto.Lastname,
            ["firstname"] = dto.Firstname,
            ["fk_soc"] = dto.ClientId.ToString(),
            ["email"] = dto.Email,
            ["phone_pro"] = dto.PhonePro,
            ["phone_perso"] = dto.PhonePerso,
            ["phone_mobile"] = dto.PhoneMobile,
            ["address"] = dto.Address,
            ["zip"] = dto.Zip,
            ["town"] = dto.Town
        };

        var response = await apiClient.PostAsync("contacts", requestBody);
        return int.Parse(response);
    }

    public async Task UpdateContactAsync(int id, UpdateContactDto dto)
    {
        var current = await apiClient.GetResourceAsync<ContactResponse>($"contacts/{id}");

        var requestBody = new Dictionary<string, object?>
        {
            ["lastname"] = dto.Lastname ?? current.lastname,
            ["firstname"] = dto.Firstname ?? current.firstname,
            ["email"] = dto.Email ?? current.email,
            ["phone_pro"] = dto.PhonePro ?? current.phone_pro,
            ["phone_perso"] = dto.PhonePerso ?? current.phone_perso,
            ["phone_mobile"] = dto.PhoneMobile ?? current.phone_mobile,
            ["address"] = dto.Address ?? current.address,
            ["zip"] = dto.Zip ?? current.zip,
            ["town"] = dto.Town ?? current.town
        };

        await apiClient.PutAsync($"contacts/{id}", requestBody);
    }

    public async Task DeleteContactAsync(int id)
    {
        await apiClient.DeleteAsync($"contacts/{id}");
    }
}