using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Internal;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Filters;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Configuration;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.Log;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Redis;
using Siger.Middlelayer.Redis.RedisEntities;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;

namespace Siger.ApiConfig.Controller
{
    public class CompanyController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerCompanyRepository _companyRepository;
        private readonly ISigerLocationProvinceRepository _provinceRepository;
        private readonly ISigerLocationCityRepository _cityRepository;
        private readonly ISigerLocationCountyRepository _countyRepository;
        private readonly ISigerProjectRepository _projectRepository;
        private readonly ISigerUserRepository _userRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly ISigerProjectTypeRepository _projectTypeRepository;
        private readonly ISigerUserPowerRepository _powerRepository;
        private readonly IAccSqlRepository _sqlRepository;
        private readonly ISigerProjectLevelRepository _sigerProjectLevel;

        public CompanyController(IUnitOfWork unitOfWork,  ISigerCompanyRepository companyRepository, ISigerLocationProvinceRepository provinceRepository, ISigerLocationCityRepository cityRepository,
            ISigerLocationCountyRepository countyRepository, ISigerProjectRepository projectRepository, ISigerUserRepository userRepository, ISigerProjectUserRepository projectUserRepository,
            ISigerProjectTypeRepository projectTypeRepository, ISigerUserPowerRepository powerRepository, IAccSqlRepository sqlRepository, ISigerProjectLevelRepository sigerProjectLevel)
        {
            _companyRepository = companyRepository;
            _provinceRepository = provinceRepository;
            _cityRepository = cityRepository;
            _countyRepository = countyRepository;
            _projectRepository = projectRepository;
            _userRepository = userRepository;
            _projectUserRepository = projectUserRepository;
            _projectTypeRepository = projectTypeRepository;
            _powerRepository = powerRepository;
            _sqlRepository = sqlRepository;
            _sigerProjectLevel = sigerProjectLevel;
            _unitOfWork = unitOfWork;
        }

        [HttpGet]
        public IActionResult GetCompanyList(string chinesename, string province, string city, string county,
            string industry_first, string industry_second, int page = 1, int pagesize = PageSize)
        {
            var result = _companyRepository.GetPagedCollectionResult(chinesename, province, city, county,
                industry_first, industry_second, page, pagesize);

            var response = new List<ResponseGetCompanyList>();

            foreach (var company in result.Data)
            {
                var p = _provinceRepository.Get(f => f.code == company.province);
                company.provinceTitle = p != null ? p.name : company.province;
                var c = _cityRepository.Get(f => f.code == company.city);
                company.cityTitle = c != null ? c.name : company.city;
                var a = _countyRepository.Get(f => f.code == company.county);
                company.countyTitle = a != null ? a.name : company.county;
                response.Add(Mapper<Company, ResponseGetCompanyList>.Map(company));
            }
            return new PagedObjectResult(response, result.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult AddCompany([FromBody]RequestAddCompany request)
        {
            var entity = _companyRepository.Get(q => q.chinesename == request.chinesename && q.status == (int)RowState.Valid);
            if (entity != null)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }
            entity = _companyRepository.Get(q => q.id == request.cid && q.status == (int)RowState.Valid);
            if (entity != null)
            {
                throw new BadRequestException(RequestEnum.IdHasExist);
            }
            var company = new siger_company
            {
                id = request.cid,
                chinesename = request.chinesename,
                chinesepinyin = request.chinesepinyin,
                //province = GetLocation(request.province, LocationType.Province),
                //city = GetLocation(request.city, LocationType.City),
                //county = GetLocation(request.county, LocationType.County),
                province = request.province,
                city = request.city,
                county = request.county,
                detailaddress = request.detailaddress,
                telephone = request.telephone,
                website = request.website,
                contact = request.contact,
                email = request.email,
                industry_first = request.industry_first.ToInt(),
                industry_second = request.industry_second.ToInt(),
                litpic = request.litpic,
                description = request.description,
                companycode = request.companycode,
                identification = request.identification,
                create_time = UnixTimeHelper.GetCurrentTime(),
                country = string.Empty
            };
            _companyRepository.Insert(company);
           
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetCompanyItem(int id)
        {
            var company = _companyRepository.Get(id);
            if (company == null || company.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.CompanyNotFound);
            }

            var response = Mapper<siger_company, ResponseGetCompanyList>.Map(company);

            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult EditCompany([FromBody] RequestUpdateCompany request)
        {
            var company = _companyRepository.Get(request.id);
            if (company == null || company.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.CompanyNotFound);
            }

            if (string.IsNullOrEmpty(request.province)|| string.IsNullOrEmpty(request.city)|| string.IsNullOrEmpty(request.county))
            {
                throw new BadRequestException(RequestEnum.ParameterMiss);
            }
            var entity = _companyRepository.Get(q => q.chinesename == request.chinesename && q.id != company.id && q.status == (int)RowState.Valid);
            if (entity != null)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }
            company.chinesename = request.chinesename;
            company.chinesepinyin = request.chinesepinyin;
            company.province = request.province;
            company.city = request.city;
            company.county = request.county;
            company.detailaddress = request.detailaddress;
            company.telephone = request.telephone;
            company.website = request.website;
            company.contact = request.contact;
            company.email = request.email;
            company.industry_first = request.industry_first.ToInt();
            company.industry_second =  request.industry_second.ToInt();
            company.litpic = request.litpic;
            company.description = request.description;
            company.companycode = request.companycode;
            company.identification = request.identification;

            _companyRepository.Update(company);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult DeleteCompany(int id)
        {
            var company = _companyRepository.Get(id);
            if (company == null || company.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.CompanyNotFound);
            }

            company.status = (int) RowState.Invalid;
            _companyRepository.Update(company);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetCompany()
        {
            var list = _companyRepository.GetList(q => q.status == (int) RowState.Valid);

            var response = new List<ResponseGetCompany>();

            foreach (var company in list)
            {
                response.Add(Mapper<siger_company, ResponseGetCompany>.Map(company));
            }

            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetCurrentCompany()
        {
            var data = new CompanyInfo
            {
                logo = string.Empty,
                remark = string.Empty
            };
            var company = _companyRepository.Get(q => q.id == CompanyId && q.status == (int) RowState.Valid);
            if (company != null)
            {
                data.logo = company.litpic;
                data.remark = company.description;
            }
            return new ObjectResult(data);
        }

        private string GetLocation(string key, LocationType locationType)
        {
            if (string.IsNullOrEmpty(key))
            {
                return string.Empty;
            }

            int.TryParse(key, out var id);
            if (id == 0)
            {
                return string.Empty;
            }
            switch (locationType)
            {
                case LocationType.Province:
                    //var province = _provinceRepository.Get(id);
                    var province = _provinceRepository.Get(f=>f.code== key);
                    if (province != null && province.status == (int)RowState.Valid)
                    {
                        return province.name;
                    }
                    break;
                case LocationType.City:
                    //var city = _cityRepository.Get(id);
                    var city = _cityRepository.Get(f=>f.code==key);
                    if (city != null && city.status == (int)RowState.Valid)
                    {
                        return city.name;
                    }
                    break;
                case LocationType.County:
                    //var county = _countyRepository.Get(id);
                    var county = _countyRepository.Get(f=>f.code==key);
                    if (county != null && county.status == (int)RowState.Valid)
                    {
                        return county.name;
                    }
                    break;
            }

            return string.Empty;
        }

        [HttpGet]
        [NoTokenValidateFilter]
        public IActionResult GetLogo(string name)
        {
            var company = _companyRepository.Get(q => q.chinesename == name && q.status == (int) RowState.Valid);
            if (company != null)
            {
                return new ObjectResult(company.litpic);
            }

            return new ObjectResult(string.Empty);
        }

        [NoTokenValidateFilter]
        [HttpPost]
        public IActionResult Register([FromBody]RequestCompanyRegister reg)
        {
            if (string.IsNullOrEmpty(reg.project.password))
                throw new BadRequestException(RequestEnum.PasswordIsEmpty);

            var result = new ResponseResultRegsiter();
            //创建company
            var companyObj = _companyRepository.Get(f => f.chinesename == reg.company.name.ToStr());

            var cid =companyObj!=null?companyObj.id:reg.company.cid;
            result.company= companyObj != null ? companyObj.chinesename : reg.company.name;
            if (cid == 0)
            {
                var company = new siger_company
                {
                    id = reg.company.cid,
                    chinesename = reg.company.name.ToStr(),
                    chinesepinyin = reg.company.nameEn.ToStr(),
                    
                    //province = GetLocation(request.province, LocationType.Province),
                    //city = GetLocation(request.city, LocationType.City),
                    //county = GetLocation(request.county, LocationType.County),
                    province = reg.company.province.ToStr(),
                    city = reg.company.city.ToStr(),
                    county=reg.company.area.ToStr(),
                    detailaddress = reg.company.address.ToStr(),
                    telephone = reg.company.phone.ToStr(),
                    //website = reg.company,
                    contact = reg.company.contacts.ToStr(),
                    email = reg.company.email.ToStr(),
                    industry_first = reg.company.industrycategory.ToInt(),
                    industry_second = reg.company.industrysecond.ToInt(),
                    litpic = reg.company.logoimg.ToStr(),
                    description = string.Empty,
                    companycode = reg.company.companycode.ToStr(),
                    identification =string.Empty,
                    create_time = UnixTimeHelper.GetCurrentTime(),
                    country = string.Empty,
                    website=string.Empty,
                    status=(int)RowState.Valid
                };
                _companyRepository.Insert(company);

                if (_unitOfWork.Commit() <= 0)
                    throw new BadRequestException(CommonEnum.SystemExcetion);

                cid = company.id;

            }
            result.companyId = cid;
            //创建project 

            var projectEntity = _projectRepository.Get(q => q.companyid == cid.ToString() && q.title == reg.project.title && q.status == (int)RowState.Valid);
            var pid = projectEntity != null ? projectEntity.id : 0;
            result.project = projectEntity != null ? projectEntity.title : reg.project.title.ToStr();


            var projectType = _projectTypeRepository.Get(reg.project.typeid);
            if (projectType == null || projectType.status != (int)RowState.Valid)
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);

            var userObj = _userRepository.Get(q => q.mobile == reg.project.account && q.status == (int)RowState.Valid);
            var uid = userObj != null ? userObj.id : 0;
            result.loginName = userObj != null ? userObj.mobile : reg.project.account;
            if (uid==0)
            {
                var user = new siger_user
                {
                    password = MD5Helper.Get32MD5(reg.project.password),
                    mobile = reg.project.account,
                    realname = reg.project.realname,
                    roleid = projectType.id,
                    type = (int)UserType.Admin
                };
                _userRepository.Insert(user);
                if (_unitOfWork.Commit() <= 0)
                    throw new BadRequestException(CommonEnum.SystemExcetion);

                uid = user.id;
            }
            result.userMid = uid;
            if (pid == 0)
            {
                var project = new siger_project
                {
                    title = reg.project.title.ToStr(),
                    typeid = reg.project.typeid,
                    companyid = cid.ToString(),
                    salesmid = reg.project.salesmid,
                    initialquotation = reg.project.initialoffer,
                    finaloffer = reg.project.finaloffer,
                    dutymid = uid,
                    mid = UserId,
                    ip = ServerIpAddress.ToStr(),
                    modular =string.Empty,
                    dashboard_ids = string.Empty,
                    createtime = UnixTimeHelper.GetNow(),
                    description=reg.project.description.ToStr(),
                };
                _projectRepository.Insert(project);
                if (_unitOfWork.Commit() <= 0)
                {
                    _userRepository.Delete(uid);
                    _unitOfWork.Commit();
                    throw new BadRequestException(CommonEnum.SystemExcetion);
                }
                else
                {
                    //todo:create dbConnect
                    InitDbConfig config = new InitDbConfig();
                    config.InitDb(cid, project.id);
                    config.InitTable(cid, project.id);
                    _sqlRepository.InitQmsData(project.id);//初始化qms模块表数据
                    _sqlRepository.InitTpmData(project.id);//初始化tpm模块表数据
                }
                pid = project.id;
            }
            result.projectId = pid;

            var projectuser = _projectUserRepository.Get(f => f.mid == uid);
            var puserId = projectuser != null ? projectuser.id : 0;
            if (puserId == 0)
            {
                var puser = new siger_project_user
                {
                    mid = uid,
                    projectid = pid,
                    name = reg.project.realname.ToStr(),
                    create_time = UnixTimeHelper.GetNow()
                };
                _projectUserRepository.Insert(puser);
            }
            //创建项目层级
            var projectLevels = _sigerProjectLevel.GetList(f => f.projectid == pid);
            if (!projectLevels.Any())
            {
                int parentid = 0;
                foreach (var level in reg.levels)
                {
                    parentid = _sigerProjectLevel.InsertAndGetId(level.title, parentid, level.id, pid);
                    if (parentid == 0)
                    {
                        _companyRepository.Delete(cid);
                        _projectRepository.Delete(pid);
                        _userRepository.Delete(uid);
                        _unitOfWork.Commit();
                        throw new BadRequestException(CommonEnum.SystemExcetion);
                    }
                }
            }
            var licenseStr = reg.licence.values;
            if (reg.licence.type == 2)
            {
                if (string.IsNullOrEmpty(licenseStr))
                {
                    throw new BadRequestException(CommonEnum.LicenseIsEmpty);
                }
            }
            else
            {
                licenseStr = GetLicense(1);
            }

            if (string.IsNullOrEmpty(licenseStr))
            {
                throw new BadRequestException(CommonEnum.LicenseIsEmpty);
            }
            var entity = new LicenseEntity
            {
                Cid = cid,
                Pid = pid,
                License = licenseStr
            };
            RedisCache.Instance.AddLicenseEntity(entity);


            return new ObjectResult(result);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="type">1:项目license 2:推送AppKey</param>
        /// <returns></returns>
        private string GetLicense(int type)
        {
            var strResult = string.Empty;
            try
            { 
                switch(type)
                {
                    case 1://SAAS一站配置项目时 设置永久 License
                        {
                            strResult = ConfigManager.GetValue("Register", "License", "");
                            break;
                        }
                    case 2: //SAAS一站配置项目时 设置APPKEY
                        {
                            strResult = ConfigManager.GetValue("Register", "AppKey", "");
                            break;
                        }
                }
              
            }
            catch(Exception  ex)
            {
                Logger.WriteLineError(ex.ToString());
            }
            return strResult;
        }
    }
}
