using Back.Common;
using Back.Data.Models;
using Back.Services;
using Back.Validations;
using FluentValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Shared.DTOs;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;

namespace Back.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BaseController : ControllerBase
    {
        private readonly ServBase _sBase;
        private readonly MobileValidation _mobilevalidation;
        private readonly servCompany _servCompany;
        private readonly servUser _servUser;
        private readonly servPermission _servPermission;
        private readonly ServValidatinMsg _servValidatinMsg;
        private readonly servSendMsg _servSendMsg;
        private readonly CompanyRegistrationValidation _companyRegistrationValidation;
        public BaseController(ServBase sBase, MobileValidation mobilevalidation
                            , servCompany servCompany, servUser servUser
                            , servPermission servPermission, ServValidatinMsg servValidatinMsg
                            , servSendMsg servSendMsg, CompanyRegistrationValidation companyRegistrationValidation)
        {
            _sBase = sBase;
            _mobilevalidation = mobilevalidation;
            _servCompany = servCompany;
            _servUser = servUser;
            _servPermission = servPermission;
            _servValidatinMsg = servValidatinMsg;
            _servSendMsg = servSendMsg;
            _companyRegistrationValidation = companyRegistrationValidation;
        }
        [HttpGet("Pricing")]
        public async Task<ActionResult<List<BasePriceDto>>> Pricing()
        => Ok(await _sBase.GetBasePrice());
        [HttpGet("DateTimeServer")]
        public async Task<ActionResult<DateTime>> DateTimeServer()
       => Ok(DateTime.Now);
        [HttpGet("LastBlog")]
        public async Task<ActionResult<PagingDto<BlogDto>>> LastBlog(int PageIndex, int PageSize)
     => Ok(await _sBase.GetBlog(PageIndex, PageSize));
        [HttpGet("GetBlogByID/{ID}")]
        public async Task<ActionResult<BlogDtoFull?>> GetBlogByID(int ID)
        {
            var result = await _sBase.GetBlogByID(ID);
            if (result == null)
                return NotFound();
            return Ok(result);
        }
        [HttpGet("LastQuestion")]
        public async Task<ActionResult<PagingDto<QuestionDto>>> LastQuestion(int PageIndex, int PageSize)
            => Ok(await _sBase.GetQuestion(PageIndex, PageSize));
        [HttpPost("CreateCsrAndPrivateKey")]
        public async Task<ActionResult<TaxToolsDTO>> CreateCsrAndPrivateKey(CsrPrivateKeyDto model)
        {
            var resultValidationmodel = await _mobilevalidation.ValidateAsync(Tuple.Create(model.Mobile, ActionMobileValidation.No));
            if (!resultValidationmodel.IsValid)
                return BadRequest(resultValidationmodel.Errors.Select(s => s.ErrorMessage).ToList());
            return Ok(await _sBase.CreateCsrAndPrivateKey(model));
        }
        [HttpPost("ReadPublicKeyFromCER")]
        public async Task<ActionResult<PublicKeyDTO>> ReadPublicKeyFromCER(string modelfromBase64)
        {
            var result = await _sBase.ReadPublicKeyFromCER(modelfromBase64);
            if (result.type == "error")
                return BadRequest();

            return Ok(result);
        }
        [HttpPost("CompanyRegistration")]
        [AllowAnonymous]
        public async Task<ActionResult<string>> CompanyRegistration([FromBody] CompanyRegistrationDTO item)
        {

            var resultValidationmodel = await _companyRegistrationValidation.ValidateAsync(item);
            if (!resultValidationmodel.IsValid)
                return BadRequest(resultValidationmodel.Errors.Select(s => s.ErrorMessage).ToList());


            try
            {
                var user = new User()
                {
                    Fullname = item.FullnameUser,
                    Mobile = item.Mobile,
                    Username = item.Username,
                    Password = item.Mobile.encrypted(),
                    IsActive = false

                };
                user = await _servUser.AddUser(user);

                var company =await  _servCompany.GetCompanyOrgByMobileAndCompanynotActive(item.Mobile);
                if (company==null)
                {
                    company = new Company()
                    {
                        Name = item.CompanyName,
                        Mobile = item.Mobile,
                        RegisterDate = DateTime.Now.ConvertMiladiToShamsi(),
                        IsActive = false

                    };
                    
                }
                else
                {
                    company.Name = item.CompanyName;
                    company.RegisterDate = DateTime.Now.ConvertMiladiToShamsi();
                    company.IsActive = false;
                }

                company = await _servCompany.AddORUpdateCompany(company);

                var allper = await _servPermission.GetPermissions();

                var roluser = new RolUser()
                {
                    CompanyID = company.ID,
                    UserID = user.ID,
                    IsAdmin = true
                };
                roluser = await _servPermission.AddRolUser(roluser);

                await _servPermission.AddRangePermissionPeriodByCompany(new List<PermissionPeriod>()
            {
                new PermissionPeriod(){CompanyID=company.ID,PermissionID=2,CalculationTypeID=2,RemainingAmount=0,TotalAmount=0},
                new PermissionPeriod(){CompanyID=company.ID,PermissionID=3,CalculationTypeID=1,RemainingAmount=5,TotalAmount=5},
                new PermissionPeriod(){CompanyID=company.ID,PermissionID=4,CalculationTypeID=1,RemainingAmount=5,TotalAmount=5},
                new PermissionPeriod(){CompanyID=company.ID,PermissionID=5,CalculationTypeID=1,RemainingAmount=5,TotalAmount=5},
                new PermissionPeriod(){CompanyID=company.ID,PermissionID=16,CalculationTypeID=1,RemainingAmount=5,TotalAmount=5},
                new PermissionPeriod(){CompanyID=company.ID,PermissionID=6,CalculationTypeID=2,RemainingAmount=0,TotalAmount=0}

            });

                await _servPermission.AddPermissionUser(roluser.ID, allper.Select(s => s.ID).ToArray());

                var modelvc = await _servValidatinMsg.GenerateCode(new VerificationCode
                {
                    prm = company.ID.ToString(),
                    val = user.ID.ToString(),
                    Type = "CompanyRegistration"
                });

                _servSendMsg.toContinue(modelvc.Code.ToString(), company.Mobile, "ثبت نام");
                return Ok(modelvc.ID);
            }
            catch (Exception ex)
            {
                //SysLog log = new SysLog()
                //{
                //    TraceIdentifierID = HttpContext.TraceIdentifier,
                //    Datetime = DateTime.Now.ConvertMiladiToShamsi(),
                //    Method = HttpContext.Request.Method,
                //    Value = ex.Message,
                //    Route = HttpContext.Request.Path,
                //    Type = "catch"
                //};
                //_contextMongodb.InsertItem(log);
                return BadRequest(new List<string> { "خطای سیستمی رخ داده" });
            }

        }
        [HttpPost("ForgetPassWord")]
        [AllowAnonymous]
        public async Task<ActionResult<string>> ForgetPassWord(ForgetPasswordItem Item) 
        {
            var resultValidationmodel = await _mobilevalidation.ValidateAsync(Tuple.Create(Item.Username, ActionMobileValidation.ExistMobile));
            if (!resultValidationmodel.IsValid)
                return BadRequest(resultValidationmodel.Errors.Select(s => s.ErrorMessage).ToList());

            var modelvc = await _servValidatinMsg.GenerateCode(new VerificationCode
            {
                prm = Item.Username,
                val = Item.PassWord,
                Type = "ForgetPassword"
            });

            _servSendMsg.toContinue(modelvc.Code.ToString(),Item.Username, "فراموشی کلمه عبور");
            return Ok(modelvc.ID);
        }
    }
}
