using AutoMapper;
using Common.Dtos;
using Common.Dtos.Company;
using Common.Validation;
using Hushian.Application.Contracts.Persistence;
using Hushian.Application.Models;
using Hushian.Domain.Entites;
using Microsoft.EntityFrameworkCore;

namespace Hushian.Application.Services
{
    public class CompanyService
    {
        private readonly IGenericRepository<Company> _CompanyRepository;
        private readonly VerificationService _VerificationService;
        private readonly IMapper _mapper;

        public CompanyService(IGenericRepository<Company> companyRepository, VerificationService verificationService, IMapper mapper)
        {
            _CompanyRepository = companyRepository;
            _VerificationService = verificationService;
            _mapper = mapper;
        }

        public async Task<ResponseBase<int>> RegisterCompany(RegisterCompanyDto dto)
        {
            ResponseBase<int> Response = new();

            var newCompany = await NewCompany(dto);
            if (newCompany.Success)
            {
                var id = await Verifi(dto.Mobile);
                Response.Value = id;
                Response.Success = id != 0;

            }
            else Response.Errors.AddRange(newCompany.Errors);

            return Response;
        }
        public async Task<ReadANDUpdate_CompanyDto?> GETCompanyinformation(int CompanyID)
        {
            var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.ID == CompanyID);
            if (company == null) return null;
            return _mapper.Map<ReadANDUpdate_CompanyDto>(company);
        }
        public async Task<ResponseBase<bool>> EditCompany(ReadANDUpdate_CompanyDto model, int CompanyID)
        {
            ResponseBase<bool> Response = new();


            if (!string.IsNullOrEmpty(model.FullNameManager) && !model.FullNameManager.IsOnlyPersianLetters())
                Response.Errors.Add("نام مدیر باید کاملا به صورت فارسی باشد");
            else if (!string.IsNullOrEmpty(model.FullName) && !model.FullName.IsOnlyPersianLetters())
                Response.Errors.Add("نام شرکت باید کاملا به صورت فارسی باشد");
            else if (!string.IsNullOrEmpty(model.Email) && !model.Email.IsValidEmail())
                Response.Errors.Add("پست الکترونیکی صحیح نمی باشد");
            else if (!string.IsNullOrEmpty(model.WebSite) && !model.WebSite.IsValidWebsite())
                Response.Errors.Add("وب سایت صحیح نمی باشد");
            else if (model.logo != null && !model.logo.IsValidImage())
                Response.Errors.Add("تصویر نمی تواند از 5 مگ بیشتر باشد");
            else
            {
                try
                {
                    var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.ID == CompanyID);

                    company.FullNameManager = model.FullNameManager;
                    company.FullName = model.FullName;
                    company.Email = model.Email;
                    company.WebSite = model.WebSite;
                    company.logo = model.logo;
                    company.allowBot = model.allowBot;
                    company.Available = model.Available;

                    if (await _CompanyRepository.UPDATEBool(company))
                    {
                        Response.Success =Response.Value= true;
                    }
                    else
                    {
                        Response.Errors.Add("خطا در ذخیره سازی");
                    }
                }
                catch (Exception)
                {
                    Response.Errors.Add("خطا سیستمی 02");
                }

            }
            return Response;
        }
        public async Task<bool> ChangeAvailableCompany(bool @checked,int CompanyID)
        {

            var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.ID == CompanyID);
            company.Available = @checked;
            return await _CompanyRepository.UPDATEBool(company);
    
        }
        public async Task<bool> ChangeallowBotCompany(bool @checked, int CompanyID)
        {
            var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.ID == CompanyID);
            company.allowBot = @checked;
            return await _CompanyRepository.UPDATEBool(company);
        }
        public async Task<ResponseBase<bool>> ChangePasswordCompany(ChangePasswordDto model, int CompanyID)
        {
            ResponseBase<bool> Response = new();

            var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.ID == CompanyID);
            if (string.IsNullOrEmpty(model.OldPassWord) || model.OldPassWord.GetHash()!=company.Password)
            {
                Response.Errors.Add("کلمه عبور فعلی صحیح نمی باشد");
            }
            else
            {
                company.Password = model.NewPassWord.GetHash();
                Response.Value= await _CompanyRepository.UPDATEBool(company);
                if (!Response.Value) Response.Errors.Add("خطا در ذخیره سازی");
                else Response.Success = true;
            }
            return Response;
        }
        public async Task<ResponseBase<int>> ForgetPasswordCompany(string Mobile)
        {
            ResponseBase<int> Response = new();

            var company = await _CompanyRepository.Get().FirstOrDefaultAsync(f => f.Mobile == Mobile);
            if (company==null)
            {
                Response.Errors.Add("کاربری یافت نشد");
            }
            else
            {
                Response.Value= await _VerificationService.GenerateCodeByForgetPassword(Mobile);
                Response.Success = true;

            }
            return Response;
        }
        private async Task<ResponseBase<bool>> NewCompany(RegisterCompanyDto dto)
        {
            ResponseBase<bool> Response = new();

            List<string> Errors = new List<string>();
            if (!dto.Mobile.CheckMobile())
            {
                Response.Errors.Add("فرمت موبایل صحیح نمی باشد");
            }
            else if (!dto.Password.CheckLawPassword(ref Errors))
            {
                Response.Errors.AddRange(Errors);
            }
            else if (!dto.FullName.IsOnlyPersianLetters())
            {
                Response.Errors.Add("نام باید کاملا به صورت فارسی باشد");
            }
            else
            {
                var AnyCompany = await _CompanyRepository.Get().FirstOrDefaultAsync(a => a.Mobile == dto.Mobile);
                if (AnyCompany != null && AnyCompany.Verified)
                {
                    Response.Errors.Add($"موبایل {dto.Mobile} در سیستم ثبت شده");
                }
                else
                {
                    if (AnyCompany != null && !AnyCompany.Verified)
                    {
                        AnyCompany.Password = dto.Password.GetHash();
                        AnyCompany.FullName = dto.FullName;
                        AnyCompany.Cdatetime = DateTime.Now;
                        if (await _CompanyRepository.UPDATEBool(AnyCompany))
                        {
                            Response.Success = true;
                        }
                        else
                        {
                            Response.Errors.Add("خطا در ذخیره سازی اطلاعات کاربر");
                        }
                    }
                    else
                    {
                        if (await _CompanyRepository.ADDBool(new Company()
                        {
                          Password = dto.Password.GetHash(),
                          FullName = dto.FullName,
                           Cdatetime = DateTime.Now,
                           Mobile=dto.Mobile
                        }))
                        {
                            Response.Success = true;
                        }
                        else
                        {
                            Response.Errors.Add("خطا در ذخیره سازی اطلاعات کاربر");
                        }
                    }
                }
            }

            return Response;
        }
        public async Task<bool> AnyCompany(int CompanyID) 
            =>await _CompanyRepository.Get().AnyAsync(a=>a.ID==CompanyID);
        public async Task<bool> AllowBot(int CompanyID)
    => await _CompanyRepository.Get().AnyAsync(a => a.ID == CompanyID && a.allowBot);
        private async Task<int> Verifi(string Mobile) => await _VerificationService.GenerateCodeByPhoneNumberConfirmed(Mobile);

    }
}
