using AutoMapper;
using DataAccessLayer;
using DataAccessLayer.Entities;
using DataAccessLayer.Filtering;
using DataAccessLayer.Units;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using WcfServices.Contract;
using WcfServices.Dto;
using WcfServices.Mapping;

namespace WcfServices.Services
{
    public partial class ISService : IDepartmentService
    {
        [PrincipalPermission(SecurityAction.Demand, Role = "VIEW_DEPARTMENTS")]
        public async Task<IEnumerable<DepartmentDto>> GetDepartmentsAsync(FilterDto filterDto)
        {
            var retval = new List<DepartmentDto>();
            using (var departmentUnit = new UnitOfWork<Department>(new ISDbContext()))
            {
                var filter = _mapper.Map<Filter>(filterDto);
                var departments = await departmentUnit.GetAsync(filter);

                foreach(var department in departments)
                {
                    retval.Add(_mapper.Map<DepartmentDto>(department));
                }
            }

            return retval;
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "VIEW_DEPARTMENTS")]
        public async Task<DepartmentDto> GetDepartmentByIdAsync(int id)
        {
            DepartmentDto retval;
            using (var departmentUnit = new UnitOfWork<Department>(new ISDbContext()))
            {
                var department = await departmentUnit.GetByIdAsync(id);

                retval = _mapper.Map<DepartmentDto>(department);
            }

            return retval;
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "EDIT_DEPARTMENTS")]
        public async Task CreateDepartmentAsync(DepartmentDto departmentDto)
        {
            using (var departmentUnit = new UnitOfWork<Department>(new ISDbContext()))
            {
                var department = _mapper.Map<Department>(departmentDto);

                if (string.IsNullOrEmpty(department.Name))
                    throw new Exception("Department must have a name.");

                await departmentUnit.CreateAsync(department);
            }
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "EDIT_DEPARTMENTS")]
        public async Task UpdateDepartmentAsync(DepartmentDto departmentDto)
        {
            using (var departmentUnit = new UnitOfWork<Department>(new ISDbContext()))
            {
                var department = _mapper.Map<Department>(departmentDto);

                if (string.IsNullOrEmpty(department.Name))
                    throw new Exception("Department must have a name.");

                await departmentUnit.UpdateAsync(department);
            }
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "EDIT_DEPARTMENTS")]
        public async Task DeleteDepartmentAsync(int id)
        {
            using (var departmentUnit = new UnitOfWork<Department>(new ISDbContext()))
            {
                var filter = new FilterDto()
                {
                    Conditions = new List<ConditionItemDto>()
                     {
                          new ConditionItemDto()
                          {
                               Column = nameof(EmployeeDto.DepartmentId),
                               Type = ConditionTypeEnum.Equal,
                               Value = id.ToString()
                          }
                     }
                };

                var departmentEmployees = await GetEmployeesAsync(filter);

                if (departmentEmployees != null && departmentEmployees.Any())
                    throw new ValidationException();

                await departmentUnit.DeleteAsync(id);
            }
        }

    }
}
