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

namespace HoneyBox.Admin.Business.Services;

/// <summary>
/// 福利屋入口服务实现
/// </summary>
public class WelfareHouseService : IWelfareHouseService
{
    private readonly HoneyBoxDbContext _dbContext;
    private readonly ILogger<WelfareHouseService> _logger;

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

    /// <inheritdoc />
    public async Task<PagedResult<WelfareHouseResponse>> GetWelfareHousesAsync(WelfareHouseListRequest request)
    {
        var query = _dbContext.WelfareHouses.AsNoTracking();

        var total = await query.CountAsync();

        var items = await query
            .OrderBy(w => w.Sort)
            .ThenByDescending(w => w.CreateTime)
            .Skip(request.Skip)
            .Take(request.PageSize)
            .ToListAsync();

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

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

    /// <inheritdoc />
    public async Task<WelfareHouseResponse?> GetWelfareHouseByIdAsync(int id)
    {
        var entity = await _dbContext.WelfareHouses
            .AsNoTracking()
            .FirstOrDefaultAsync(w => w.Id == id);

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


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

        var now = (int)DateTimeOffset.Now.ToUnixTimeSeconds();
        var entity = new Model.Entities.WelfareHouse
        {
            Name = request.Name,
            Image = request.Image,
            Url = request.Url,
            Sort = request.Sort,
            Status = (byte)request.Status,
            CreateTime = now,
            UpdateTime = now
        };

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

        _logger.LogInformation("创建福利屋入口成功: Id={Id}, Name={Name}", entity.Id, entity.Name);

        return entity.Id;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateWelfareHouseAsync(int id, WelfareHouseUpdateRequest request)
    {
        var entity = await _dbContext.WelfareHouses.FirstOrDefaultAsync(w => w.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "福利屋入口不存在");
        }

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

        entity.Name = request.Name;
        entity.Image = request.Image;
        entity.Url = request.Url;
        entity.Sort = request.Sort;
        entity.Status = (byte)request.Status;
        entity.UpdateTime = (int)DateTimeOffset.Now.ToUnixTimeSeconds();

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

        _logger.LogInformation("更新福利屋入口成功: Id={Id}", id);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> DeleteWelfareHouseAsync(int id)
    {
        var entity = await _dbContext.WelfareHouses.FirstOrDefaultAsync(w => w.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "福利屋入口不存在");
        }

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

        _logger.LogInformation("删除福利屋入口成功: Id={Id}", id);

        return result;
    }

    /// <inheritdoc />
    public async Task<bool> UpdateStatusAsync(int id, WelfareHouseStatusRequest request)
    {
        var entity = await _dbContext.WelfareHouses.FirstOrDefaultAsync(w => w.Id == id);
        if (entity == null)
        {
            throw new BusinessException(BusinessErrorCodes.NotFound, "福利屋入口不存在");
        }

        entity.Status = (byte)request.Status;
        entity.UpdateTime = (int)DateTimeOffset.Now.ToUnixTimeSeconds();

        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(WelfareHouseCreateRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Name))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "名称不能为空");
        }

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

        if (string.IsNullOrWhiteSpace(request.Url))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "跳转链接不能为空");
        }
    }

    /// <summary>
    /// 验证更新请求必填字段
    /// </summary>
    private static void ValidateUpdateRequest(WelfareHouseUpdateRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Name))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "名称不能为空");
        }

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

        if (string.IsNullOrWhiteSpace(request.Url))
        {
            throw new BusinessException(BusinessErrorCodes.ValidationFailed, "跳转链接不能为空");
        }
    }

    /// <summary>
    /// 将实体映射为响应模型
    /// </summary>
    private static WelfareHouseResponse MapToResponse(Model.Entities.WelfareHouse entity)
    {
        return new WelfareHouseResponse
        {
            Id = entity.Id,
            Name = entity.Name,
            Image = entity.Image,
            Url = entity.Url,
            Sort = entity.Sort,
            Status = entity.Status,
            CreateTime = entity.CreateTime.HasValue 
                ? DateTimeOffset.FromUnixTimeSeconds(entity.CreateTime.Value).LocalDateTime 
                : null
        };
    }

    #endregion
}
