using FamilyTreeAPI.Entities;
using FamilyTreeAPI.Interface;
using FamilyTreeAPI.Models;
using Microsoft.EntityFrameworkCore;

namespace FamilyTreeAPI.Repository
{
    public class LookupRepository: ILookup
    {
        private readonly FamilyTreeDBContext _context;
        public LookupRepository(FamilyTreeDBContext context)
        {
            _context = context;
        }

        private bool checkDescription(string desc, string type, int id)
        {
            bool result = false;
            if (!string.IsNullOrEmpty(desc))
            {
                string ldesc = desc.ToLower();
                int count = _context.Lookups.Where(x => (x.Code ?? "").ToLower() == ldesc
                && id != x.Id
                ).ToList().Count();
                result = count > 0;

            }
            return result;
        }
        public async Task<ResultModel<int>> SaveLookupAsync(LookupEditDto lookup)
        {
            int result = -1;
            int statusCode = 0;
            string desc = lookup.Description.Trim();
            string error = "";
            try
            {
                Lookup model = null!;
                bool ok = !checkDescription(desc, lookup.Type, lookup.Id);
                if (ok)
                {
                    if (lookup.Id < 1)
                    {
                        model = new();
                        model.Code = lookup.CodeId;
                        model.Description = desc;
                        model.Type = lookup.Type;
                        model.Lactive = lookup.Active;
                        
                        _context.Lookups.Add(model);

                    }
                    else
                    {
                        Lookup? model1 = await _context.Lookups.FindAsync(lookup.Id);
                        if (model1 != null)
                        {
                            model1.Description = desc;
                            model1.Code = lookup.CodeId;
                            model1.Lactive = lookup.Active;
                        }

                    }

                    await _context.SaveChangesAsync();
                    if (model != null)
                        result = model.Id;

                    statusCode = 1;
                }
                else
                {
                    statusCode = 0;
                    error = "description is already in database";
                }
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
               
            }
            return new ResultModel<int>()
            {
                Data = result,
                StatusCode = statusCode,
                Message = error
            };
        }
        public async Task<ResultModel<LookupEditDto>> GetLookupEditByIdAsync(int id, string type)
        {
            List<LookupEditDto> resultList;
            LookupEditDto item = null!;
            int statusCode = 0;
            string error = "";
            try
            {
                resultList = await _context.Lookups.Where(x => x.Type == type
                   && (x.Id == id))
                    .Select(item => new LookupEditDto
                    {
                        CodeId = string.IsNullOrEmpty(item.Code) ? "0": item.Code,
                        Active = item.Lactive ?? false,
                        Id = item.Id,
                        Description = item.Description ?? ""
                    })
                    .ToListAsync();

                if (resultList.Count > 0)
                    item = resultList[0];
                statusCode = 1;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
                
            }
            return new ResultModel<LookupEditDto>()
            {
                Data = item,
                StatusCode = statusCode,
                Message = error
            };
        }
        public async Task<ResultModel<List<LookupDto>>> GetLookupAsync(string type)
        {
            List<LookupDto> resultList = new();
            int statusCode = 0;
            string error = "";
            try
            {
                resultList = await _context.Lookups.Where(x => x.Type == type && ((x.Lactive ?? false) == true))
                    .Select(item => new LookupDto { Id = item.Id, CodeId = item.Code ?? "", Description = item.Description ?? "" })
                    .ToListAsync();

                resultList.Sort((x, y) => x.Description.CompareTo(y.Description));
                
                statusCode = 1;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
                
            }
            return new ResultModel<List<LookupDto>>()
            {
                Data = resultList,
                StatusCode = statusCode,
                Message = error
            };
        }

        public async Task<ResultModel<Dictionary<string, LookupDto>>> GetLookupDicAsync(string type)
        {
            Dictionary<string, LookupDto> resultList = new();

            int statusCode = 0;
            string error = "";
            try
            {
                resultList = await _context.Lookups.Where(x => x.Type == type && ((x.Lactive ?? false) == true))
                   .Select(item => new LookupDto { Id = item.Id, CodeId = item.Code ?? "", Description = item.Description ?? "" })
                   .ToDictionaryAsync(x => x.CodeId);


                statusCode = 1;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
                
            }
            return new ResultModel<Dictionary<string, LookupDto>>()
            {
                Data = resultList,
                StatusCode = statusCode,
                Message = error
            };
        }
        public async Task<ResultModel<List<LookupEditDto>>> GetLookupEditAsync(string type)
        {
            List<LookupEditDto> resultList = new();
            int statusCode = 0;
            string error = "";
            try
            {
                resultList = await _context.Lookups.Where(x => x.Type == type)
                    .Select(item => new LookupEditDto
                    {
                        Id = item.Id,
                        Active = item.Lactive ?? false,
                        CodeId = item.Code ?? "",
                        Type = item.Type ?? "",
                        Description = item.Description ?? ""
                    })
                    .ToListAsync();

                resultList.Sort((x, y) => x.Description.CompareTo(y.Description));

                statusCode = 1;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
               
            }
            return new ResultModel<List<LookupEditDto>>()
            {
                Data = resultList,
                StatusCode = statusCode,
                Message = error
            };
        }
        public async Task<ResultModel<List<LookupDto>>> GetPersonsAsync()
        {
            List<LookupDto> resultList = new();
            int statusCode = 0;
            string error = "";
            try
            {
                resultList = await _context.Persons.Where(x => x.Alive == true)
                    .Select(item => new LookupDto { Id = item.Id, CodeId = item.Id.ToString(), Description = item.FirstName ?? "" })
                    .ToListAsync();

                resultList.Sort((x, y) => x.Description.CompareTo(y.Description));

                statusCode = 1;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
               
            }
            return new ResultModel<List<LookupDto>>()
            {
                Data = resultList,
                StatusCode = statusCode,
                Message = error
            };
        }

        public async Task<ResultModel<List<LookupDto>>> GetStaffAsync()
        {
            List<LookupDto> resultList = new();
            int statusCode = 0;
            string error = "";
            try
            {
                resultList = await _context.staff.Where(x => x.Sactive == true)
                    .Select(item => new LookupDto { Id = item.Id, CodeId = item.Firstname ?? "", Description = item.Lastname ?? "" })
                    .ToListAsync();

                resultList.Sort((x, y) => x.Description.CompareTo(y.Description));

                statusCode = 1;
            }
            catch (Exception ex)
            {
                error = ex.ToString();
                statusCode = -1;
                
            }
            return new ResultModel<List<LookupDto>>()
            {
                Data = resultList,
                StatusCode = statusCode,
                Message = error
            };
        }

       
    }
}
