using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using HoneyBox.Model.Models.Address;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Core.Services;

/// <summary>
/// 地址服务实现
/// </summary>
public class AddressService : IAddressService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<AddressService> _logger;
    private const int MaxAddressCount = 10;

    public AddressService(HoneyBoxDbContext dbContext, ILogger<AddressService> logger)
    {
        _dbContext = dbContext;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task<AddressDto> AddAddressAsync(int userId, AddAddressRequest request)
    {
        // 检查地址数量限制
        var addressCount = await _dbContext.UserAddresses
            .CountAsync(a => a.UserId == userId && a.IsDeleted == 0);

        if (addressCount >= MaxAddressCount)
        {
            throw new InvalidOperationException("最多只能添加10个收货地址");
        }

        var now = DateTime.Now;
        var address = new UserAddress
        {
            UserId = userId,
            ReceiverName = request.ReceiverName,
            ReceiverPhone = request.ReceiverPhone,
            DetailedAddress = request.DetailedAddress,
            IsDefault = (byte)(request.IsDefault == 1 ? 1 : 0),
            IsDeleted = 0,
            CreatedAt = now,
            UpdatedAt = now
        };

        // 如果设置为默认地址，将其他地址设为非默认
        if (address.IsDefault == 1)
        {
            await SetOtherAddressNotDefaultAsync(userId);
        }

        // 如果是第一个地址，自动设为默认
        if (addressCount == 0)
        {
            address.IsDefault = 1;
        }

        _dbContext.UserAddresses.Add(address);
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("Address added: UserId={UserId}, AddressId={AddressId}", userId, address.Id);
        return MapToDto(address);
    }


    /// <inheritdoc />
    public async Task<AddressDto> UpdateAddressAsync(int userId, UpdateAddressRequest request)
    {
        var address = await _dbContext.UserAddresses
            .FirstOrDefaultAsync(a => a.Id == request.Id && a.UserId == userId && a.IsDeleted == 0);

        if (address == null)
        {
            throw new InvalidOperationException("地址不存在");
        }

        address.ReceiverName = request.ReceiverName;
        address.ReceiverPhone = request.ReceiverPhone;
        address.DetailedAddress = request.DetailedAddress;
        address.UpdatedAt = DateTime.Now;

        // 处理默认地址设置
        if (request.IsDefault.HasValue && request.IsDefault.Value == 1 && address.IsDefault != 1)
        {
            await SetOtherAddressNotDefaultAsync(userId, address.Id);
            address.IsDefault = 1;
        }

        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("Address updated: UserId={UserId}, AddressId={AddressId}", userId, address.Id);
        return MapToDto(address);
    }

    /// <inheritdoc />
    public async Task<AddressDto?> GetDefaultAddressAsync(int userId)
    {
        // 先查找默认地址
        var address = await _dbContext.UserAddresses
            .FirstOrDefaultAsync(a => a.UserId == userId && a.IsDefault == 1 && a.IsDeleted == 0);

        // 如果没有默认地址，返回最新添加的一条
        if (address == null)
        {
            address = await _dbContext.UserAddresses
                .Where(a => a.UserId == userId && a.IsDeleted == 0)
                .OrderByDescending(a => a.Id)
                .FirstOrDefaultAsync();
        }

        return address != null ? MapToDto(address) : null;
    }

    /// <inheritdoc />
    public async Task<List<AddressDto>> GetAddressListAsync(int userId)
    {
        var addresses = await _dbContext.UserAddresses
            .Where(a => a.UserId == userId && a.IsDeleted == 0)
            .OrderByDescending(a => a.IsDefault)
            .ThenByDescending(a => a.Id)
            .ToListAsync();

        return addresses.Select(MapToDto).ToList();
    }

    /// <inheritdoc />
    public async Task<bool> DeleteAddressAsync(int userId, int addressId)
    {
        var address = await _dbContext.UserAddresses
            .FirstOrDefaultAsync(a => a.Id == addressId && a.UserId == userId && a.IsDeleted == 0);

        if (address == null)
        {
            throw new InvalidOperationException("地址不存在");
        }

        // 软删除
        address.IsDeleted = 1;
        address.UpdatedAt = DateTime.Now;
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("Address deleted: UserId={UserId}, AddressId={AddressId}", userId, addressId);
        return true;
    }

    /// <inheritdoc />
    public async Task<bool> SetDefaultAddressAsync(int userId, int addressId)
    {
        var address = await _dbContext.UserAddresses
            .FirstOrDefaultAsync(a => a.Id == addressId && a.UserId == userId && a.IsDeleted == 0);

        if (address == null)
        {
            throw new InvalidOperationException("地址不存在");
        }

        // 已经是默认地址
        if (address.IsDefault == 1)
        {
            return true;
        }

        // 将其他地址设为非默认
        await SetOtherAddressNotDefaultAsync(userId);

        // 设置当前地址为默认
        address.IsDefault = 1;
        address.UpdatedAt = DateTime.Now;
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("Default address set: UserId={UserId}, AddressId={AddressId}", userId, addressId);
        return true;
    }

    /// <inheritdoc />
    public async Task<AddressDto?> GetAddressDetailAsync(int userId, int addressId)
    {
        var address = await _dbContext.UserAddresses
            .FirstOrDefaultAsync(a => a.Id == addressId && a.UserId == userId && a.IsDeleted == 0);

        return address != null ? MapToDto(address) : null;
    }

    /// <summary>
    /// 将其他地址设为非默认
    /// </summary>
    private async Task SetOtherAddressNotDefaultAsync(int userId, int? exceptId = null)
    {
        var query = _dbContext.UserAddresses
            .Where(a => a.UserId == userId && a.IsDefault == 1 && a.IsDeleted == 0);

        if (exceptId.HasValue)
        {
            query = query.Where(a => a.Id != exceptId.Value);
        }

        await query.ExecuteUpdateAsync(s => s.SetProperty(a => a.IsDefault, (byte)0));
    }

    /// <summary>
    /// 将实体映射为DTO
    /// </summary>
    private static AddressDto MapToDto(UserAddress address)
    {
        return new AddressDto
        {
            Id = address.Id,
            UserId = address.UserId,
            ReceiverName = address.ReceiverName,
            ReceiverPhone = address.ReceiverPhone,
            DetailedAddress = address.DetailedAddress,
            IsDefault = address.IsDefault ?? 0,
            CreateTime = address.CreatedAt.ToString("yyyy-MM-dd HH:mm:ss"),
            UpdateTime = address.UpdatedAt.ToString("yyyy-MM-dd HH:mm:ss")
        };
    }
}
