using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.UI;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using YGNT.Infrastructure.Extension;
using YGNT.Infrastructure.Helper;
using YGNT.Infrastructure.Model;
using YGNT.QuestionLibrary.Chapters.Dto;
using YGNT.QuestionLibrary.Core.Chapters;
using YGNT.QuestionLibrary.Core.Chapters.Domain;
using YGNT.QuestionLibrary.Core.IRepositories;
using YGNT.QuestionLibrary.Core.Models;
using YGNT.QuestionLibrary.Extension;

namespace YGNT.QuestionLibrary.Chapters
{
    /// <summary>
    /// 章节管理
    /// </summary>
    public class ChapterAppService : IChapterAppService
    {
        private readonly IChapterManager _chapterManager;
        private readonly IChapterTreePathManager _chapterTreePathManager;
        private readonly IChapterRepository _chapterRepository;
        private readonly IRepository<Chapter, long> _chapterRepository2;
        private readonly IHttpHelper _httpHelper;
        private readonly ITextbookRepository _textbookRepository;
        private readonly IDisciplineRepository _disciplineRepository;

        public ChapterAppService(IChapterManager chapterManager,
            IChapterRepository chapterRepository, 
            IChapterTreePathManager chapterTreePathManager, 
            IRepository<Chapter, long> chapterRepository2,
            IHttpHelper httpHelper,
            ITextbookRepository textbookRepository)
        {
            _chapterManager = chapterManager;
            _chapterRepository = chapterRepository;
            _chapterTreePathManager = chapterTreePathManager;
            _chapterRepository2 = chapterRepository2;
            _httpHelper = httpHelper;
            _textbookRepository = textbookRepository;
        }

        /// <summary>
        /// 查询章节列表
        /// </summary>
        /// <param name="search"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ChapterItemDto>> GetListAsync(SearchChapterInputDto search)
        {
            var queryable = _chapterRepository.GetAll()
                .WhereIf(!search.KeyWord.IsNullOrEmpty(), x => x.Name.Contains(search.KeyWord))
                .WhereIf(search.ParentId.HasValue, x => x.ParentId == search.ParentId)
                //.Where(x => x.ParentId == search.ParentId)
                .Where(x => x.TextbookId == search.TextbookId)
                .OrderBy(x => x.ParentId)
                .ThenBy(x => x.Sort);

            var result = await queryable.GetResultAsync(search, x => x.Adapt(new ChapterItemDto()
            {
                Discipline = x.Discipline.Name,
                Textbook = x.Textbook.Name,
                HasChild = x.ChildChapters.Any()
            }), default(long));
            foreach (var chapterItemDto in result.Items)
            {
                chapterItemDto.Path = await _chapterTreePathManager.GetNamePathAsync(chapterItemDto.Id);
            }
            return result;
        }

        /// <summary>
        /// 获取章节详细信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ChapterDto> GetInfoAsync([Required] long id)
        {
            var chapter = await _chapterRepository.GetAll()
                .Where(x => x.Id == id)
                .Select(x => x.Adapt(new ChapterDto()
                {
                    Discipline = x.Discipline.Name,
                    Textbook = x.Textbook.Name,
                    HasChild = x.ChildChapters.Any()
                })).FirstOrDefaultAsync();
            chapter.Path = await _chapterTreePathManager.GetNamePathAsync(id);
            return chapter;
        }

        /// <summary>
        /// 获取章节名称路径
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<string> GetNamePathAsync([Required] long id)
        {
            return await _chapterTreePathManager.GetNamePathAsync(id);
        }

        /// <summary>
        /// 获取课本下的所有章节
        /// </summary>
        /// <param name="textbookId">课本id</param>
        /// <returns></returns>
        public async Task<List<GetChapterTextbookAllDto>> GetChapterTextbookAllAsync([Required] long textbookId)
        {
            var chapter = await _chapterRepository2.GetAll()
                .Where(x => x.TextbookId == textbookId)
                .OrderBy(x => x.ParentId).ThenBy(x => x.Sort)
                .Select(x => x.Adapt(new GetChapterTextbookAllDto()))
                .ToListAsync();
            return chapter;
        }

        /// <summary>
        /// 获取所有可用章节
        /// </summary>
        /// <returns></returns>
        public async Task<List<GetChapterAllDto>> GetAllAsync()
        {
            var chapter = await _chapterRepository2.GetAll()
                .OrderBy(x => x.TextbookId).ThenBy(x => x.ParentId).ThenBy(x => x.Sort)
                .Select(x => x.Adapt(new GetChapterAllDto()))
                .ToListAsync();
            return chapter;
        }

        /// <summary>
        /// 新建章节
        /// </summary>
        /// <param name="create"></param>
        /// <returns></returns>
        public async Task<long> CreateAsync(CreateChapterDto create)
        {
            var chapter = await _chapterManager.CreateAsync(create.Name, create.TextBookId, create.ParentId, create.Remark);
            return chapter.Id;
        }

        /// <summary>
        /// 修改章节信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="update"></param>
        /// <returns></returns>
        public async Task UpdateAsync([Required] long id, UpdateChapterDto update)
        {
            var chapter = await _chapterRepository.GetAsync(id);
            update.Adapt(chapter);
            await _chapterManager.CheckNameAsync(chapter.Name, chapter.TextbookId);
            await _chapterRepository.UpdateAsync(chapter);
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="sort"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task SortAsync(SortDto<long> sort)
        {
            var chapter = await _chapterRepository.GetAsync(sort.Id);
            await _chapterManager.SortAsync(chapter, sort.SortType);
        }

        /// <summary>
        /// 删除章节
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync([Required] long id)
        {
            await _chapterManager.DeleteAsync(id);
        }

        /// <summary>
        /// 同步章节
        /// </summary>
        /// <returns></returns>
        public async Task DataSyncAsync()
        {
            HttpResult httpResult = await _httpHelper.GetAsync($"{AppSettings.App("App", "SyncAddress")}/v1/material/chapter/find/all");
            if (httpResult.Success)
            {
                /*var sourceList = await _chapterRepository.GetAllListAsync();
                foreach (var item in sourceList.OrderByDescending(i=>i.Id))
                {
                    await _chapterRepository.DeleteAsync(item);
                }*/
                var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ChapterSyncDto>>(httpResult.Data.ToString());
                foreach (var item in list.OrderBy(i => i.id))
                {
                    try
                    {
                        var textbook = await _textbookRepository.GetAll()
                            .Where(x => x.Id == item.material_id)
                            .FirstOrDefaultAsync();
                        if (textbook == null) continue;
                        var isExist = await _chapterRepository.GetAll().AnyAsync(x => x.Id == item.id);
                        if (isExist)
                        {
                            var chapter = await _chapterRepository.GetAsync(item.id);
                            chapter.Name = item.name;
                            chapter.DisciplineId = textbook.DisciplineId;
                            isExist = true;
                            if (item.parent_id > 0)
                            {
                                isExist = await _chapterRepository.GetAll().AnyAsync(x => x.Id == item.parent_id);
                            }

                            if (isExist)
                            {
                                await _chapterRepository.UpdateAsync(chapter);
                            }
                        }
                        else
                        {
                            var chapter = new Chapter { Id = item.id, Name = item.name, TextbookId = item.material_id, ParentId = item.parent_id, Sort = item.sort };

                            chapter.DisciplineId = textbook.DisciplineId;
                            isExist = true;
                            if (item.parent_id > 0)
                            {
                                isExist = await _chapterRepository.GetAll().AnyAsync(x => x.Id == item.parent_id);
                            }
                            if (isExist)
                            {
                                await _chapterRepository.InsertAndGetIdAsync(chapter);
                            }
                        }

                    }
                    catch (Exception ex)
                    {
                        throw new UserFriendlyException(ex.Message);
                    }
                }
            }
            else
            {
                throw new UserFriendlyException(httpResult.Message);
            }
        }
    }
}