using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HRM.BO;
using Org.BouncyCastle.Asn1.X509.Qualified;
using Microsoft.AspNetCore.Authorization;

namespace HRM.UI.Controllers.Payroll
{
    [Route("api/organogram")]
    [ApiController]
    [Authorize]
    public class OrganogramController : ControllerBase
    {
        private readonly IOGPositionTypeService _ogPositionTypeService;
        private readonly IOrganogramService _organogramService;
        private readonly IOrganogramEmployeeService _organogramEmployeeService;
        private readonly ISkillService _skillService;
        private readonly ISkillLevelService _skillLevelService;

        public OrganogramController(IOGPositionTypeService ogPositionTypeService,
            IOrganogramService organogramService,
            IOrganogramEmployeeService organogramEmployeeService,
            ISkillService skillService,
            ISkillLevelService skillLevelService)
        {
            this._ogPositionTypeService = ogPositionTypeService;
            this._organogramService = organogramService;
            this._organogramEmployeeService = organogramEmployeeService;
            this._skillService = skillService;
            this._skillLevelService = skillLevelService;
        }

        // OGPositionType
        [HttpGet("getOGPositionTypeById/{id}")]
        public ActionResult GetOGPositionTypeById(int id)
        {
            OGPositionType ogPositionType = new OGPositionType();
            try
            {
                ogPositionType = _ogPositionTypeService.Get(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ogPositionType);
        }

        [HttpGet("getAllOGPositionType")]
        public ActionResult GetAllOGPositionType()
        {
            List<OGPositionType> ogPositionTypes = new List<OGPositionType>();
            try
            {
                ogPositionTypes = _ogPositionTypeService.Get();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ogPositionTypes);
        }

        [HttpGet("getOGPositionTypeByStatus/{status}")]
        public ActionResult GetOGPositionTypeByStatus(EnumStatus status)
        {
            List<OGPositionType> ogPositionTypes = new List<OGPositionType>();
            try
            {
                ogPositionTypes = _ogPositionTypeService.Get(status);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ogPositionTypes);
        }

        [HttpGet("isOGPositionTypeExists/{code}")]
        public ActionResult IsOGPositionTypeExists(string code)
        {
            bool ans;
            try
            {
                ans = _ogPositionTypeService.IsExists(code);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ans);
        }

        [HttpPost]
        [Route("saveOGPositionType")]
        public ActionResult SaveOGPositionType(OGPositionType ogPositionType)
        {
            try
            {
                _ogPositionTypeService.Save(ogPositionType);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ogPositionType);
        }

        [HttpPost]
        [Route("deleteOGPositionTypeById")]
        public ActionResult DeleteOGPositionTypeById(int id)
        {
            try
            {
                _ogPositionTypeService.Delete(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok();
        }

        // OrganogramBasic
        [HttpGet("getOrganogramBasicById/{id}")]
        public ActionResult GetOrganogramBasicById(int id)
        {
            OrganogramBasic organogramBasic = new OrganogramBasic();
            try
            {
                organogramBasic = _organogramService.Get(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramBasic);
        }

        [HttpGet("getOrganogramBasicByEmployeeId/{employeeId}")]
        public ActionResult GetOrganogramBasicByEmployeeId(int employeeId)
        {
            OrganogramBasic organogramBasic = new OrganogramBasic();
            try
            {
                organogramBasic = _organogramService.GetbyEmployeeid(employeeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramBasic);
        }

        [HttpGet("getOrganogramBasicByStatus/{status}")]
        public ActionResult GetOrganogramBasicByStatus(EnumStatus status)
        {
            List<OrganogramBasic> organogramBasics = new List<OrganogramBasic>();
            try
            {
                organogramBasics = _organogramService.Get(status);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramBasics);
        }


        [HttpGet("getOrganogramBasicByParentId/{parentId}/{status}")]
        public ActionResult GetOrganogramBasicByParentId(int parentId, EnumStatus status)
        {
            List<OrganogramBasic> organogramBasics = new List<OrganogramBasic>();
            try
            {
                organogramBasics = _organogramService.GetByParentID(parentId, status);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramBasics);
        }

        [HttpGet("getMinNodeIdByDept/{deptId}")]
        public ActionResult GetMinNodeIdByDept(int deptId)
        {
            int ans;
            try
            {
                ans = _organogramService.GetMinNodeIdByDept(deptId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ans);
        }


        [HttpGet("getOrganogramBasicTopParents/{status}")]
        public ActionResult GetOrganogramBasicTopParents(EnumStatus status)
        {
            List<OrganogramBasic> organogramBasics = new List<OrganogramBasic>();
            try
            {
                organogramBasics = _organogramService.GetTopParents(status);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramBasics);
        }

        [HttpGet("get4OrganAuthority/{nodeId}")]
        public ActionResult Get4OrganAuthority(int nodeId)
        {
            List<OrganogramAuthority> organogramAuthorities = new List<OrganogramAuthority>();
            try
            {
                organogramAuthorities = _organogramService.Get4OrganAuthority(nodeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramAuthorities);
        }

        [HttpGet("get4OrganDelegation/{nodeId}")]
        public ActionResult Get4OrganDelegation(int nodeId)
        {
            List<OrganogramDelegation> items = new List<OrganogramDelegation>();
            try
            {
                items = _organogramService.Get4OrganDelegation(nodeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("get4OrganJobDesc/{nodeId}")]
        public ActionResult Get4OrganJobDesc(int nodeId)
        {
            List<OrganogramJobDesc> items = new List<OrganogramJobDesc>();
            try
            {
                items = _organogramService.Get4OrganJobDesc(nodeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("get4OrganResponsibility/{nodeId}")]
        public ActionResult Get4OrganResponsibility(int nodeId)
        {
            List<OrganogramResponsibility> items = new List<OrganogramResponsibility>();
            try
            {
                items = _organogramService.Get4OrganResponsibility(nodeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("get4OrganSkilLevel/{nodeId}")]
        public ActionResult Get4OrganSkilLevel(int nodeId)
        {
            List<OrganogramSkillLevel> items = new List<OrganogramSkillLevel>();
            try
            {
                items = _organogramService.Get4OrganSkilLevel(nodeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getByPositionTypeID/{positionTypeId}")]
        public ActionResult GetByPositionTypeID(int positionTypeId)
        {
            List<OrganogramBasic> items = new List<OrganogramBasic>();
            try
            {
                items = _organogramService.GetbyPositionTypeID(positionTypeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getAllOrganPosition")]
        public ActionResult GetAllOrganPosition()
        {
            List<OrganogramPosition> items = new List<OrganogramPosition>();
            try
            {
                items = _organogramService.GetAllOrganPosition();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganAuthorityByEmp/{employeeId}")]
        public ActionResult GetOrganAuthorityByEmp(int employeeId)
        {
            List<OrganogramAuthority> items = new List<OrganogramAuthority>();
            try
            {
                items = _organogramService.GetOrganAuthorityByEmp(employeeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganogramBasicMaxTier")]
        public ActionResult GetOrganogramBasicMaxTier()
        {
            int ans;
            try
            {
                ans = _organogramService.MaxTier();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ans);
        }

        [HttpGet("getOrganAuthorityByTier/{fromTier}/{toTier}")]
        public ActionResult GetOrganAuthorityByTier(int fromTier, int toTier)
        {
            List<OrganogramBasic> items = new List<OrganogramBasic>();
            try
            {
                items = _organogramService.GetbyTier(fromTier, toTier);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpPost]
        [Route("saveOrganogramBasic")]
        public ActionResult SaveOrganogramBasic(OrganogramBasic item)
        {
            CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);
            if (item.IsNew == false)
            {
                item.ModifiedBy = currentUser.UserID;
                item.ModifiedDate = DateTime.Today;
            }
            else

            {
                item.CreatedBy = currentUser.UserID;
                item.CreatedDate = DateTime.Today;
            }

            try
            {
                _organogramService.Save(item);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(item.ID);
        }

        [HttpPost]
        [Route("CreateOrgFromEmployee")]
        public ActionResult CreateOrgFromEmployee(dynamic item)
        {
            CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);


            try
            {
                _organogramService.CreateOrgFromEmployee(currentUser.UserID);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(true);
        }
        


        [HttpPost]
        [Route("updateParentAndTier")]
        public ActionResult UpdateParentAndTier(List<OrganogramBasic> items)
        {
            try
            {
                _organogramService.UpdateParentAndTier(items);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpPost]
        [Route("deleteOrganogramBasic")]
        public ActionResult DeleteOrganogramBasic(OrganogramBasic org)
        {
            try
            {
                _organogramService.Delete(org.ID);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok();
        }

        // OrganogramEmployee
        [HttpGet("getOrganogramInfo")]
        public ActionResult GetOrganogramInfo()
        {
            List<OrganogramBasic> items = new List<OrganogramBasic>();
            try
            {
                items = _organogramEmployeeService.GetOrganogramInfo();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganogramEmployee/{nodeId}")]
        public ActionResult getOrganogramEmployee(int nodeId)
        {
            List<OrganogramEmployee> items = new List<OrganogramEmployee>();
            try
            {
                items = _organogramEmployeeService.Get(nodeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganogramEmployeeByEmpId/{empId}")]
        public ActionResult GetOrganogramEmployeeByEmpId(int empId)
        {
            List<OrganogramEmployee> items = new List<OrganogramEmployee>();
            try
            {
                items = _organogramEmployeeService.GetByEmp(empId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganogramEmployeeByTier/{tierFrom}/{tierTo}")]
        public ActionResult GetOrganogramEmployeeByTier(int tierFrom, int tierTo)
        {
            List<OrganogramEmployee> items = new List<OrganogramEmployee>();
            try
            {
                items = _organogramEmployeeService.GetByTier(tierFrom, tierTo);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganogramEmployeeByPositionType/{positionType}")]
        public ActionResult GetOrganogramEmployeeByPositionType(EnumOGPositionType positionType)
        {
            List<OrganogramEmployee> items = new List<OrganogramEmployee>();
            try
            {
                items = _organogramEmployeeService.GetByPositionType(positionType);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getAllOrganogramEmployee")]
        public ActionResult GetAllOrganogramEmployee()
        {
            List<OrganogramEmployee> items = new List<OrganogramEmployee>();
            try
            {
                items = _organogramEmployeeService.Get();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getOrganogramEmployeeByGrades/{gradeId}")]
        public ActionResult GetOrganogramEmployeeByGrades(string gradeId)
        {
            List<OrganogramEmployee> items = new List<OrganogramEmployee>();
            try
            {
                items = _organogramEmployeeService.GetByGrades(gradeId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpPost]
        [Route("saveOrganogramEmployee")]
        public ActionResult SaveOrganogramEmployee(OrganogramEmployee organogramEmployee)
        {
            try
            {
                _organogramEmployeeService.Save(organogramEmployee);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramEmployee);
        }

        [HttpPost]
        [Route("saveOrganogramEmployeeList")]
        public ActionResult SaveOrganogramEmployeeList(List<OrganogramEmployee> organogramEmployees)
        {
            try
            {
                _organogramEmployeeService.Save(organogramEmployees);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(organogramEmployees);
        }

        [HttpPost]
        [Route("deleteOrganogramEmployee")]
        public ActionResult DeleteOrganogramEmployee(int id)
        {
            try
            {
                _organogramEmployeeService.Delete(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok();
        }

        // Skill
        [HttpGet("getSkillById/{id}")]
        public ActionResult GetSkillById(int id)
        {
            Skill item = new Skill();
            try
            {
                item = _skillService.Get(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(item);
        }

        [HttpGet("getAllSkill")]
        public ActionResult GetAllSkill()
        {
            List<Skill> items = new List<Skill>();
            try
            {
                items = _skillService.Get();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getParents/{status}")]
        public ActionResult GetParents(EnumStatus status)
        {
            List<Skill> items = new List<Skill>();
            try
            {
                items = _skillService.GetParents(status);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getChilds/{parentId}")]
        public ActionResult GetChilds(int parentId)
        {
            List<Skill> items = new List<Skill>();
            try
            {
                items = _skillService.GetChilds(parentId);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("isSkillExists/{code}")]
        public ActionResult IsSkillExists(string code)
        {
            bool ans;
            try
            {
                ans = _skillService.IsExists(code);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ans);
        }

        [HttpPost]
        [Route("saveSkill")]
        public ActionResult SaveSkill(Skill skill)
        {
            try
            {
                _skillService.Save(skill);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok();
        }

        [HttpPost]
        [Route("deleteSkillById")]
        public ActionResult DeleteSkillById(int id)
        {
            try
            {
                _skillService.Delete(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok();
        }

        // SkillLevel

        [HttpGet("getSkillLevelById/{id}")]
        public ActionResult GetSkillLevelById(int id)
        {
            SkillLevel skillLevel = new SkillLevel();
            try
            {
                skillLevel = _skillLevelService.Get(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(skillLevel);
        }

        [HttpGet("getAllSkillLevel")]
        public ActionResult GetAllSkillLevel()
        {
            List<SkillLevel> items = new List<SkillLevel>();
            try
            {
                items = _skillLevelService.Get();
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("getSkillLevelByStatus/{status}")]
        public ActionResult GetSkillLevelByStatus(EnumStatus status)
        {
            List<SkillLevel> items = new List<SkillLevel>();
            try
            {
                items = _skillLevelService.Get(status);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(items);
        }

        [HttpGet("isSkillLevelExists/{code}")]
        public ActionResult IsSkillLevelExists(string code)
        {
            bool ans;
            try
            {
                ans = _skillLevelService.IsExists(code);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(ans);
        }

        [HttpPost]
        [Route("saveSkillLevel")]
        public ActionResult SaveSkillLevel(SkillLevel skillLevel)
        {
            try
            {
                _skillLevelService.Save(skillLevel);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(skillLevel);
        }

        [HttpPost]
        [Route("deleteSkillLevelById")]
        public ActionResult DeleteSkillLevelById(int id)
        {
            try
            {
                _skillLevelService.Delete(id);
            }
            catch (Exception e)
            {
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok();
        }
    }
}