using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using detect.gui.Models;
using detect.gui.Models.Entities;
using Microsoft.EntityFrameworkCore;

namespace detect.gui.Services.Detect;

public class DetectUserService : ServiceBase<DetectUserService, UserEntity>
{
    public ApiResponse<UserEntity?> Login(string? username, string? password)
    {
        if (string.IsNullOrWhiteSpace(username))
            return new ApiResponse<UserEntity?>(-1, "用户名不能为空");
        if (string.IsNullOrWhiteSpace(password))
            return new ApiResponse<UserEntity?>(-1, "密码不能为空");
        var user = Find(u => u.Username != null && u.Password != null && u.Username.Equals(username) && u.Password.Equals(password));
        return user == null ? new ApiResponse<UserEntity?>(-1, "用户名或密码不对") : new ApiResponse<UserEntity?>(0, null, user);
    }
    public ApiResponse<UserEntity?> GetDataById(long id)
    {
        var item = Find(x => x.Id == id);
        if (item != null)
        {
            var userAuth = Context!.Set<UserAuthorityEntity>().Where(x => x.UserId == item.Id).ToList();
            var authIds = userAuth.Select(x => x.AuthorityId).ToList();
            item.AuthorityList = Context!.Set<AuthorityEntity>().Where(x => authIds.Contains(x.Id)).ToList();
        }
        return new ApiResponse<UserEntity?>(0, null, item);
    }
    public ApiResponse<List<UserEntity>?> ListAll()
    {
        var items = FindList(x => true, "Id", true).ToList();
        items.ForEach(entity =>
        {
            var userAuth = Context!.Set<UserAuthorityEntity>().Where(x => x.UserId == entity.Id).ToList();
            var authIds = userAuth.Select(x => x.AuthorityId).ToList();
            entity.AuthorityList = Context!.Set<AuthorityEntity>().Where(x => authIds.Contains(x.Id)).ToList();
        });
        return new ApiResponse<List<UserEntity>?>(0, null, items);
    }
    
    public ApiResponse<PagedResult<UserEntity>> Search(string? realName = "", int pageNum = 1, int pageSize = 10)
    {
        Expression<Func<UserEntity,bool>> filter = x => string.IsNullOrEmpty(realName) || string.IsNullOrEmpty(x.RealName) || x.RealName.Contains(realName);
        var total = Count(filter);
        var items = FindList(filter, "CreateTime", false)
            .Skip((pageNum - 1) * pageSize).Take(pageSize).ToList();
        items.ForEach(entity =>
        {
            var userAuth = Context!.Set<UserAuthorityEntity>().Where(x => x.UserId == entity.Id).ToList();
            var authIds = userAuth.Select(x => x.AuthorityId).ToList();
            entity.AuthorityList = Context!.Set<AuthorityEntity>().Where(x => authIds.Contains(x.Id)).ToList();
        });
        var pagedResult = new PagedResult<UserEntity>(pageNum, pageSize, total, items);
        return new ApiResponse<PagedResult<UserEntity>>(0, "success", pagedResult);
    }
    
    public ApiResponse<List<UserEntity>?> List(Expression<Func<UserEntity, bool>> whereLambda)
    {
        var items = FindList(whereLambda, "Id", true).ToList();
        items.ForEach(entity =>
        {
            var userAuth = Context!.Set<UserAuthorityEntity>().Where(x => x.UserId == entity.Id).ToList();
            var authIds = userAuth.Select(x => x.AuthorityId).ToList();
            entity.AuthorityList = Context!.Set<AuthorityEntity>().Where(x => authIds.Contains(x.Id)).ToList();
        });
        return new ApiResponse<List<UserEntity>?>(0, null, items);
    }
    
    public ApiResponse<UserEntity?> AddData(UserEntity entity)
    {
        var user = Add(entity);
        if (entity.AuthorityList is { Count: > 0 })
        {
            entity.AuthorityList.ForEach(authorityEntity =>
            {
                var userAuth = new UserAuthorityEntity()
                {
                    UserId = user.Id,
                    AuthorityId = authorityEntity.Id,
                };
                Context!.Set<UserAuthorityEntity>().Add(userAuth);
            });
        }
        return new ApiResponse<UserEntity?>(0, null, user);
    }
    
    public ApiResponse<UserEntity?> UpdateData(UserEntity entity)
    {
        var user = Find(x => x.Id == entity.Id);
        user!.RealName = entity.RealName;
        user.UpdateTime = DateTime.Now;
        if (entity.AuthorityList is { Count: > 0 })
        {
            Context!.Set<UserAuthorityEntity>().Where(x => x.UserId == user.Id).ExecuteDelete();
            entity.AuthorityList.ForEach(authorityEntity =>
            {
                var userAuth = new UserAuthorityEntity()
                {
                    UserId = user.Id,
                    AuthorityId = authorityEntity.Id,
                };
                Context!.Set<UserAuthorityEntity>().Add(userAuth);
            });
        }
        return new ApiResponse<UserEntity?>(Update(entity) ? 0 : -1, null, null);
    }
    
    public ApiResponse<UserEntity?> DeleteData(long id)
    {
        Delete(x => x.Id == id);
        return new ApiResponse<UserEntity?>(0, null, null);
    }
}