using HoneyBox.Admin.Business.Models;
using HoneyBox.Admin.Business.Models.FloatBall;
using HoneyBox.Admin.Business.Services.Interfaces;
using HoneyBox.Model.Data;
using HoneyBox.Model.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace HoneyBox.Admin.Business.Services;

/// <summary>
/// 悬浮球配置服务实现
/// </summary>
public class FloatBallService : IFloatBallService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<FloatBallService> _logger;

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

    /// <inheritdoc />
    public async Task<PagedResult<FloatBallResponse>> GetFloatBallsAsync(FloatBallListRequest request)
    {
        var query = _dbContext.FloatBallConfigs.AsNoTracking();

        var total = await query.CountAsync();

        var items = await query
            .OrderByDescending(f => f.CreatedAt)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

        var list = items.Select(MapToResponse).ToList();

        return PagedResult<FloatBallResponse>.Create(list, total, request.Page, request.PageSize);
    }

    /// <inheritdoc />
    public async Task<FloatBallResponse?> GetFloatBallByIdAsync(int id)
    {
        var entity = await _dbContext.FloatBallConfigs
            .AsNoTracking()
            .FirstOrDefaultAsync(f => f.Id == id);

        return entity == null ? null : MapToResponse(entity);
    }

    /// <inheritdoc />
    public async Task<int> CreateFloatBallAsync(FloatBallCreateRequest request)
    {
        // 验证必填字段
        ValidateCreateRequest(request);

        var entity = new FloatBallConfig
        {
            Title = request.Title,
            Type = (byte)request.Type,
            Image = request.Image,
            ImageBj = request.ImageBj,
            ImageDetails = request.ImageDetails,
            LinkUrl = request.LinkUrl ?? string.Empty,
            PositionX = request.PositionX,
            PositionY = request.PositionY,
            Width = request.Width,
            Height = request.Height,
            ImageDetailsX = request.ImageDetailsX,
            ImageDetailsY = request.ImageDetailsY,
            ImageDetailsW = request.ImageDetailsW,
            ImageDetailsH = request.ImageDetailsH,
            Effect = (byte)request.Effect,
            Status = (byte)request.Status,
            CreatedAt = DateTime.Now,
            UpdatedAt = DateTime.Now
        };

        _dbContext.FloatBallConfigs.Add(entity);
        await _dbContext.SaveChangesAsync();

        _logger.LogInformation("创建悬浮球成功: Id={Id}, Title={Title}", entity.Id, entity.Title);

        return entity.Id;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateFloatBallAsync(int id, FloatBallUpdateRequest request)
    {
        var entity = await _dbContext.FloatBallConfigs.FirstOrDefaultAsync(f => f.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "悬浮球配置不存在");
        }

        // 验证必填字段
        ValidateUpdateRequest(request);

        entity.Title = request.Title;
        entity.Type = (byte)request.Type;
        entity.Image = request.Image;
        entity.ImageBj = request.ImageBj;
        entity.ImageDetails = request.ImageDetails;
        entity.LinkUrl = request.LinkUrl ?? string.Empty;
        entity.PositionX = request.PositionX;
        entity.PositionY = request.PositionY;
        entity.Width = request.Width;
        entity.Height = request.Height;
        entity.ImageDetailsX = request.ImageDetailsX;
        entity.ImageDetailsY = request.ImageDetailsY;
        entity.ImageDetailsW = request.ImageDetailsW;
        entity.ImageDetailsH = request.ImageDetailsH;
        entity.Effect = (byte)request.Effect;
        entity.Status = (byte)request.Status;
        entity.UpdatedAt = DateTime.Now;

        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("更新悬浮球成功: Id={Id}", id);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> DeleteFloatBallAsync(int id)
    {
        var entity = await _dbContext.FloatBallConfigs.FirstOrDefaultAsync(f => f.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "悬浮球配置不存在");
        }

        _dbContext.FloatBallConfigs.Remove(entity);
        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("删除悬浮球成功: Id={Id}", id);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateStatusAsync(int id, FloatBallStatusRequest request)
    {
        var entity = await _dbContext.FloatBallConfigs.FirstOrDefaultAsync(f => f.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "悬浮球配置不存在");
        }

        entity.Status = (byte)request.Status;
        entity.UpdatedAt = DateTime.Now;

        var result = await _dbContext.SaveChangesAsync() > 0;

        _logger.LogInformation("更新悬浮球状态: Id={Id}, Status={Status}", id, request.Status);

        return result;
    }

    #region Private Helper Methods

    /// <summary>
    /// 验证创建请求必填字段
    /// </summary>
    private static void ValidateCreateRequest(FloatBallCreateRequest request)
    {
        if (request.Type < 1 || request.Type > 2)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "类型必须为1(展示图片)或2(跳转页面)");
        }

        if (string.IsNullOrWhiteSpace(request.Image))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "悬浮球图片不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.PositionX))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "X轴位置不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.PositionY))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "Y轴位置不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.Width))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "宽度不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.Height))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "高度不能为空");
        }

        if (request.Effect < 0 || request.Effect > 1)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "特效必须为0(无)或1(缩放动画)");
        }
    }

    /// <summary>
    /// 验证更新请求必填字段
    /// </summary>
    private static void ValidateUpdateRequest(FloatBallUpdateRequest request)
    {
        if (request.Type < 1 || request.Type > 2)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "类型必须为1(展示图片)或2(跳转页面)");
        }

        if (string.IsNullOrWhiteSpace(request.Image))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "悬浮球图片不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.PositionX))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "X轴位置不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.PositionY))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "Y轴位置不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.Width))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "宽度不能为空");
        }

        if (string.IsNullOrWhiteSpace(request.Height))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "高度不能为空");
        }

        if (request.Effect < 0 || request.Effect > 1)
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "特效必须为0(无)或1(缩放动画)");
        }
    }

    /// <summary>
    /// 将实体映射为响应模型
    /// </summary>
    private static FloatBallResponse MapToResponse(FloatBallConfig entity)
    {
        return new FloatBallResponse
        {
            Id = entity.Id,
            Title = entity.Title,
            Type = entity.Type,
            Image = entity.Image,
            ImageBj = entity.ImageBj,
            ImageDetails = entity.ImageDetails,
            LinkUrl = entity.LinkUrl,
            PositionX = entity.PositionX,
            PositionY = entity.PositionY,
            Width = entity.Width,
            Height = entity.Height,
            ImageDetailsX = entity.ImageDetailsX,
            ImageDetailsY = entity.ImageDetailsY,
            ImageDetailsW = entity.ImageDetailsW,
            ImageDetailsH = entity.ImageDetailsH,
            Effect = entity.Effect,
            Status = entity.Status,
            CreatedAt = entity.CreatedAt
        };
    }

    #endregion
}
