using Ewide.Core.Extension;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ewide.Application.Service
{
    [ApiDescriptionSettings(Name = "HouseCompany")]
    public class HouseCompanyService : IHouseCompanyService, IDynamicApiController, ITransient
    {
        private readonly IRepository<BsHouseCompany> _bsHouseCompanyRep;

        public HouseCompanyService(IRepository<BsHouseCompany> bsHouseCompanyRep)
        {
            _bsHouseCompanyRep = bsHouseCompanyRep;
        }

        [HttpPost("/houseCompany/page")]
        public async Task<dynamic> Page([FromBody] HouseCompanyPageInput input)
        {
            var config = new TypeAdapterConfig().ForType<BsHouseCompany, HouseCompanyDetailOutput>()
                .Map(target => target.Info, src => JsonConvert.DeserializeObject<List<HouseCompanyInfoOutput>>(src.Info))
                .Config;
            return await _bsHouseCompanyRep.DetachedEntities.ToPageData<BsHouseCompany, HouseCompanyDetailOutput>(input, config);
        }

        [HttpPost("/houseCompany/add")]
        public async Task Add([FromBody] HouseCompanyAddInput input)
        {
            var info = JsonConvert.SerializeObject(input.Info);
            var config = new TypeAdapterConfig().ForType<HouseCompanyAddInput, BsHouseCompany>()
                .Map(target => target.Info, src => JsonConvert.SerializeObject(src.Info))
                .Config;
            var company = input.Adapt<BsHouseCompany>(config);
            await company.InsertAsync();
        }

        [HttpPost("/houseCompany/edit")]
        public async Task Edit([FromBody] HouseCompanyEditInput input)
        {
            var config = new TypeAdapterConfig().ForType<HouseCompanyEditInput, BsHouseCompany>()
                .Map(target => target.Info, src => JsonConvert.SerializeObject(src.Info))
                .Config;
            var company = input.Adapt<BsHouseCompany>(config);
            await company.UpdateAsync();
        }

        [HttpPost("/houseCompany/delete")]
        public async Task Delete([FromBody] HouseCompanyInput input)
        {
            var company = await _bsHouseCompanyRep.FirstOrDefaultAsync(p => p.Id.Equals(input.Id));
            await company.DeleteAsync();
        }

        [HttpGet("/houseCompany/detail")]
        public async Task<HouseCompanyDetailOutput> Detail([FromQuery] HouseCompanyInput input)
        {
            var company = await _bsHouseCompanyRep.FirstOrDefaultAsync(p => p.Id.Equals(input.Id));
            var config = new TypeAdapterConfig().ForType<BsHouseCompany, HouseCompanyDetailOutput>()
                .Map(target => target.Info, src => JsonConvert.DeserializeObject<List<HouseCompanyInfoOutput>>(src.Info))
                .Config;
            var output = company.Adapt<HouseCompanyDetailOutput>(config);
            return output;
        }

        [HttpGet("/houseCompany/list")]
        public async Task<dynamic> List([FromQuery] HouseCompanyListInput input)
        {
            var types = input.Type.Split(',');
            var result = new List<HouseCompanyDetailOutput>();
            var config = new TypeAdapterConfig().ForType<BsHouseCompany, HouseCompanyDetailOutput>()
                .Map(target => target.Info, src => JsonConvert.DeserializeObject<List<HouseCompanyInfoOutput>>(src.Info))
                .Config;
            foreach (var type in types)
            {
                var list = (await _bsHouseCompanyRep.DetachedEntities
                    .Where(p => EF.Functions.Like(p.Type, $"%[{type.Trim()}]%"))
                    .OrderBy(p => p.Name)
                    .ToListAsync())
                    .Select(p =>
                    {
                        var output = p.Adapt<HouseCompanyDetailOutput>(config);
                        return output;
                    });
                result.AddRange(list);
            }

            return result.Distinct();
        }
    }
}
