using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZhonTai.Admin.Core.Consts;
using ZhonTai.Admin.Services.User;
using ZhonTai.DynamicApi.Attributes;
using ZhonTai.DynamicApi;
using Microsoft.AspNetCore.Mvc;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Domain.Role;
using ZhonTai.Admin.Domain.User;
using ZhonTai.Admin.Services.User.Dto;
using ZhonTai.Admin.Domain.UserRole;
using ZhonTai.Admin.Domain.Project;
using ZhonTai.Admin.Services.Project.Dto;
using ZhonTai.Admin.Core.Attributes;
using ZhonTai.Admin.Domain.Tenant;
using ZhonTai.Admin.Domain.TenantPkg;
using ZhonTai.Admin.Domain.Pkg;
using ZhonTai.Admin.Repositories;
using ZhonTai.Admin.Services.Tenant.Dto;
using System.Linq.Expressions;
using ZhonTai.Admin.Domain.Org;
using ZhonTai.Admin.Services.Pkg;
using ZhonTai.Admin.Domain.ProjectLink;

namespace ZhonTai.Admin.Services.Project
{
    /// <summary>
    /// 项目服务
    /// </summary>
    [Order(10)]
    [DynamicApi(Area = AdminConsts.AreaName)]
    public partial class ProjectService : BaseService, IProjectService, IDynamicApi
    {
        private readonly IProjectRepository _projectRepository;
        private readonly IProjectPriceRepository _projectPriceRepository;
        private readonly IProjectRecordRepository _projectRecordRepository;
        private readonly IProjectLinkRepository _projectLinkRepository;

        public ProjectService(IProjectRepository projectRepository, IProjectPriceRepository projectPriceRepository, IProjectRecordRepository projectRecordRepository,IProjectLinkRepository projectLinkRepository)
        {
            _projectRepository = projectRepository;
            _projectPriceRepository = projectPriceRepository;
            _projectRecordRepository = projectRecordRepository;
            _projectLinkRepository = projectLinkRepository;
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ProjectGetOutput> GetAsync(long id)
        {
            var project = await _projectRepository.Select
            .WhereDynamic(id)
            .FirstAsync(a => new ProjectGetOutput
            {
                Name = a.Name,
                Logo = a.Logo,
                Tips = a.Tips,
                SettleDay = a.SettleDay,
                MaxPrice = a.MaxPrice,
                Works = a.Works,
                VideoUrl = a.VideoUrl,
                Detail = a.Detail,
                Id = a.Id,
                prices = _projectPriceRepository.Select.Where(m => m.ProjectId == a.Id).ToList<ProjectPriceAddInput>()
            });
            return project;
        }

        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageOutput<ProjectGetPageOutput>> GetPageAsync(PageInput<ProjectGetPageInput> input)
        {
            string keywords = input?.Filter.Keywrods;
            int? status = input?.Filter?.Status;
            var list = await _projectRepository.Select
                .WhereIf(keywords.NotNull(), (m) => m.Name.Contains(keywords))
                .WhereIf(status != null && status > 0, (m) => m.Status == status)
            .Count(out var total)
            .OrderByDescending(true, a => a.Id)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync<ProjectGetPageOutput>();

            var data = new PageOutput<ProjectGetPageOutput>()
            {
                List = Mapper.Map<List<ProjectGetPageOutput>>(list),
                Total = total
            };

            return data;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [AdminTransaction]
        public async Task<long> AddAsync(ProjectAddInput input)
        {

            //添加项目
            ProjectEntity entity = Mapper.Map<ProjectEntity>(input);
            entity.Status = 1;
            ProjectEntity project = await _projectRepository.InsertAsync(entity);
            long projectId = project.Id;

            //添加项目价格            
            var prices = input.prices.Select(m => new ProjectPriceEntity
            {
                ProjectId = projectId,
                Name = m.Name,
                Price = m.Price
            }).ToList();

            await _projectPriceRepository.InsertAsync(prices);

            return 1;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task UpdateAsync(ProjectUpdateInput input)
        {
            throw ResultOutput.Exception("暂未开发");

            var project = await _projectRepository.GetAsync(input.Id);
            if (!(project?.Id > 0))
            {
                throw ResultOutput.Exception("项目不存在");
            }

            //更新项目
            await _projectRepository.UpdateDiy.SetSource(
            new ProjectEntity()
            {
                Id = project.Id,
                Name = input.Name,
                Logo = input.Logo,
                Tips = input.Tips,
                SettleDay = input.SettleDay,
                MaxPrice = input.MaxPrice,
                Works = input.Works,
                VideoUrl = input.VideoUrl,
                Detail = input.Detail,
            })
            .UpdateColumns(a => new { a.Name, a.Logo, a.Tips, a.SettleDay, a.MaxPrice, a.VideoUrl, a.Detail, a.ModifiedTime }).ExecuteAffrowsAsync();

            //删除项目价格
            var PriceIds = _projectPriceRepository.Select.Where(m => m.ProjectId == project.Id).ToList(m => m.Id);
            var inputPrice = input.prices.Where(m => m.Id > 0).ToList();
            var inputPriceIds = inputPrice.Select(m => m.Id).ToList();
            var deletePriceIds = PriceIds.Except(inputPriceIds).ToList();
            if (deletePriceIds.Count() > 0)
            {
                await _projectPriceRepository.SoftDeleteAsync(a => deletePriceIds.Contains(a.Id));
            }
            //新增项目价格
            var addPriceIds = input.prices.Where(m => m.Id <= 0).ToList();
            if (addPriceIds.Count() > 0)
            {
                var list = addPriceIds.Select(m => new ProjectPriceEntity
                {
                    ProjectId = project.Id,
                    Name = m.Name,
                    Price = m.Price
                }).ToList();
                await _projectPriceRepository.InsertAsync(list);
            }
            //更新项目价格
            foreach (var item in inputPrice)
            {
                await _projectPriceRepository.UpdateDiy.SetSource(
                    new ProjectPriceEntity()
                    {
                        Id = item.Id,
                        Name = item.Name,
                        Price = item.Price
                    })
                .UpdateColumns(a => new { a.Name, a.Price, a.ModifiedTime }).ExecuteAffrowsAsync();
            }



        }

        /// <summary>
        /// 更新状态
        /// </summary>
        ///<param name="Id"></param>
        ///<param name="status">状态 2上架 3下架 4暂停</param>
        /// <returns></returns>
        public async Task UpdateStatusAsync(long Id, int status)
        {
            var project = await _projectRepository.GetAsync(Id);
            if (!(project?.Id > 0))
            {
                throw ResultOutput.Exception("项目不存在");
            }
            if (!new int[] { 2, 3, 4, 5 }.Contains(status))
            {
                throw ResultOutput.Exception("请做出有效操作");
            }
            //上架项目需要验证推广码是否大于0
            if (status == 2) { 
                var count= await _projectLinkRepository.Where(m=>m.ProjectId==Id&&m.IsUse==0).CountAsync();
                if (count <= 0) {
                    throw ResultOutput.Exception("请去上传推广码");
                }
            }



            string statusText = GetStatusText(project.Status);
            string statusText2 = GetStatusText(status);

            string remark = $"{project.Name}从{statusText}变更为{statusText2}";

            //更新项目
            await _projectRepository.UpdateDiy.SetSource(
            new ProjectEntity()
            {
                Id = project.Id,
                Status = status,
            })
            .UpdateColumns(a => new { a.Status }).ExecuteAffrowsAsync();

            //项目记录
            await _projectRecordRepository.InsertAsync(new ProjectRecordEntity()
            {
                ProjectId = Id,
                Remark = remark,
                Type = status,
            });
        }
        #region 私有方法
        /// <summary>
        /// 获取项目状态
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        private static string GetStatusText(int status) => status switch
        {
            1 => "待上架",
            2 => "上架",
            3 => "下架",
            4 => "暂停",
            5 => "名额已满",
            _ => "未知状态"
        };
        #endregion

    }
}