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

namespace FamilyTreeAPI.Repository;

public class RelationShipRepository: IRelationShipd
{
    private readonly FamilyTreeDBContext _context;
    private readonly IHttpContextAccessor _httpContext;
    private readonly IConfiguration _config;
    public RelationShipRepository(IConfiguration config, FamilyTreeDBContext context, IHttpContextAccessor httpContext)
    {
        _context = context;
        _config = config;
        _httpContext = httpContext;
    }
    private RelationShip FillModel(RelationShipDto dto, RelationShip model)
    {
        model.RelatePersonId = dto.RelatePersonId;
        model.PersonId = dto.PersonId;
        return model;
    }

    private RelationShipDto FillDto(RelationShip model)
    {
        RelationShipDto dto = new();
        dto.Id = model.Id;
        dto.PersonId = model.PersonId;
        dto.RelatePersonId = model.RelatePersonId;
        return dto;
    }
    public async Task<ResultModel<int>> SaveAsync(List<RelationShipDto> list)
    {
        int statusCode = 0;
        string error = "";
        RelationShipDto item;
        RelationShip model;
        try
        {
            for (int i = 0; i < list.Count; i++)
            {
                item = list[i];
                if (item.Id < 1)
                {
                    model = new();
                    model = FillModel(item, model);
                    _context.RelationShips.Add(model);
                }
                else if (item.State == enumState.Modify)
                {
                    RelationShip? RelationShip = await _context.RelationShips.FindAsync(item.Id);
                    if (RelationShip != null)
                    {
                        RelationShip = FillModel(item, RelationShip);
                    }
                }
                else if (item.State == enumState.Delete)
                {
                    RelationShip? RelationShip = await _context.RelationShips.FindAsync(item.Id);
                    if (RelationShip != null)
                    {
                        _context.RelationShips.Remove(RelationShip);
                    }
                }
            }

            statusCode = 1;
            await _context.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            error = ex.ToString();
            statusCode = -1;
        }

        return new ResultModel<int>
        {
            StatusCode = statusCode,
            Data = statusCode,
            Message = error
        };
    }

    public async Task<ResultModel<List<RelationShipDto>>> GetByPersonIdAsync(int personId)
    {
        string error = "";
        int statusCode = -1;
        List<RelationShipDto>  list = new();
        RelationShipDto dto;
        RelationShip model;
        try
        {


            var mlist = await _context.RelationShips.Where(x => x.PersonId == personId).ToListAsync();
            for (int i = 0; i < mlist.Count; i++)
            {
                model = mlist[i];
                dto = FillDto(model);
                list.Add(dto);
            }
            var rlist = await _context.RelationShips.Where(x => x.RelatePersonId == personId).ToListAsync();
            for (int i = 0; i < rlist.Count; i++)
            {
                model = rlist[i];
                dto = FillDto(model);
                list.Add(dto);
            }

            statusCode = 1;
        }
        catch (Exception ex)
        {
            error = ex.ToString();
            statusCode = -1;
        }

        return new ResultModel<List<RelationShipDto>>
        {
            StatusCode = statusCode,
            Data = list,
            Message = error
        };
    }
    
    public async Task<ResultModel<RelationShipDto>> GetByIdAsync(int Id)
    {
        string error = "";
        int statusCode = -1;
        
        RelationShipDto dto =new();
        RelationShip? model;
        try
        {


            model = await _context.RelationShips.FindAsync(Id);
            if (model != null)
                dto = FillDto(model);
                        
        }
        catch (Exception ex)
        {
            error = ex.ToString();
            statusCode = -1;
        }

        return new ResultModel<RelationShipDto>
        {
            StatusCode = statusCode,
            Data = dto,
            Message = error
        };
    }

    public async Task<ResultModel<int>> DeleteAsync(int Id)
    {
        int result = -1;
        string error = "";
        int statusCode = -1;
        try
        {
            RelationShip? RelationShip = await _context.RelationShips.FindAsync(Id);
            if (RelationShip != null)
            {
                _context.RelationShips.Remove(RelationShip);
            }
        }
        catch (Exception e)
        {
            error = e.ToString();
            statusCode = -1;
        }
       
        return new ResultModel<int>
        {
            StatusCode = statusCode,
            Data = result,
            Message = error
        };
    }
}