using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Common.Extensions;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.AccRepository.Entities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.AccRepository.Request;
using Siger.Middlelayer.AccRepository.Response;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Common.Helpers;

namespace Siger.ApiACC.Controllers
{
    public class StationBaseSettingController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerBaseSetting _baseSetting;
        private readonly ISigerBaseSettingItem _baseSettingItem;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSection;

        public StationBaseSettingController(IUnitOfWork unitOfWork, ISigerBaseSetting baseSetting, ISigerBaseSettingItem baseSettingItem
           , ISigerProjectLevelSectionRepository sigerProjectLevelSection)
        {
            _unitOfWork = unitOfWork;
            _baseSetting = baseSetting;
            _baseSettingItem = baseSettingItem;
            _sigerProjectLevelSection = sigerProjectLevelSection;
        }

        [HttpGet]
        public IActionResult GetItemList(int page = 1, int pagesize = 10)
        {
            var Data = _baseSettingItem.GetList(t => t.projectId == ProjectId && t.status == (int)RowState.Valid).ToList();

            var response = new List<ResponseBaseSettingItem>();
            foreach (var item in Data)
            {
                var users = _baseSetting.GetUserInfo(item.UID.ToInt(), ProjectId);
                response.Add(new ResponseBaseSettingItem
                {
                    id = item.id,
                    groupname = item.GroupName,
                    seq = item.Seq,
                    item = item.Item,
                    descr = item.Descr,
                    manualkeyin = item.ManualKeyIN,
                    uid = item.UID,
                    uid_value = users != null ? users.name : "",
                    transdatetime = item.TransDateTime.ToString(ParameterConstant.DateTimeFormat)
                });
            }

            return new PagedObjectResult(response, response.Count(), page, pagesize);
        }

        [HttpPost]
        public IActionResult Save([FromBody]RequestSaveBaseSetting request)
        {
            var olddatas = _baseSetting.GetList(t => t.Line == request.Line && t.Station == request.Station && t.status == (int)RowState.Valid && t.projectId == ProjectId);
            if (olddatas.Any())
            {
                foreach (var data in olddatas)
                {
                    data.status = (int)RowState.Invalid;
                    _baseSetting.Update(data);
                }
            }
            if (request != null && request.data != null && request.data.Any())
            {
                var saveList = new List<SigerTrBaseSetting>();
                foreach (var item in request.data)
                {
                    saveList.Add(new SigerTrBaseSetting
                    {
                        Line = request.Line,
                        Station = request.Station,
                        GroupName = item.GroupName,
                        Seq = item.Seq,
                        Item = item.Item,
                        Value = item.Value,
                        TransDateTime = DateTime.Now,
                        UID = UserId.ToStr(),
                        projectId = ProjectId
                    });
                }
                _baseSetting.Insert(saveList);
            }
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetList(int line, int station, int page = 1, int pagesize = 10)
        {
            Expression<Func<SigerTrBaseSetting, bool>> Funcat = f => f.projectId == ProjectId && f.status == RowState.Valid.GetHashCode();
            Expression<Func<SigerTrBaseSetting, bool>> Funline = f => true;
            Expression<Func<SigerTrBaseSetting, bool>> Funstation = f => true;

            if (line > 0)
                Funline = f => f.Line == line;
            if (station > 0)
                Funstation = f => f.Station == station;
            var predicate = Funcat.And(Funline).And(Funstation).And(Funline);
            var Data = _baseSetting.GetPagedList(page, pagesize, predicate);

            var response = new List<ResponseBaseSetting>();
            foreach (var item in Data.Data)
            {
                var lines = _sigerProjectLevelSection.Get(t => t.id == item.Line && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                var stations = _sigerProjectLevelSection.Get(t => t.id == item.Station && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                var users = _baseSetting.GetUserInfo(item.UID.ToInt(), ProjectId);
                var desc = _baseSettingItem.Get(f => f.projectId.Equals(ProjectId) && f.status == (int)RowState.Valid && f.Seq.Equals(item.Seq));
                response.Add(new ResponseBaseSetting
                {
                    id = item.id,
                    groupname = item.GroupName,
                    seq = item.Seq,
                    item = item.Item,
                    value = item.Value,
                    uid = item.UID,
                    uid_value = users != null ? users.name : "",
                    line = item.Line,
                    station = item.Station,
                    line_value = lines != null ? lines.title : "",
                    station_value = stations != null ? stations.title : "",
                    transdatetime = item.TransDateTime.ToString(ParameterConstant.DateTimeFormat),
                    descr = desc.Descr
                });
            }

            return new PagedObjectResult(response, Data.Total, page, pagesize);
        }

        [HttpPost]
        public IActionResult Duplicate([FromBody]RequestDuplicate duplicate)
        {
            if (duplicate.fromstation > 0 && duplicate.tostation > 0)
            {
                var query = _baseSetting.GetList(t => t.status == (int)RowState.Valid && t.projectId == ProjectId && t.Line == duplicate.fromline && t.Station == duplicate.fromstation).ToList();
                if (query.Any())
                {
                    var saveList = new List<SigerTrBaseSetting>();
                    foreach (var item in query)
                    {
                        saveList.Add(new SigerTrBaseSetting
                        {
                            Line = duplicate.toline,
                            Station = duplicate.tostation,
                            GroupName = item.GroupName,
                            Seq = item.Seq,
                            Item = item.Item,
                            Value = item.Value,
                            TransDateTime = DateTime.Now,
                            UID = UserId.ToStr(),
                            projectId = ProjectId
                        });
                    }
                    _baseSetting.Insert(saveList);
                    if (_unitOfWork.Commit() > 0)
                        return new ObjectResult(CommonEnum.Succefull);
                }
            }
            else
            {
                var query = _baseSetting.GetDataList(duplicate.fromline, duplicate.toline, ProjectId).ToList();
                if (query.Any())
                {
                    var saveList = new List<SigerTrBaseSetting>();
                    foreach (var item in query)
                    {
                        saveList.Add(new SigerTrBaseSetting
                        {
                            Line = duplicate.toline,
                            Station = duplicate.tostation,
                            GroupName = item.GroupName,
                            Seq = item.Seq,
                            Item = item.Item,
                            Value = item.Value,
                            TransDateTime = DateTime.Now,
                            UID = UserId.ToStr()
                        });
                    }
                    _baseSetting.Insert(saveList);
                    if (_unitOfWork.Commit() > 0)
                        return new ObjectResult(CommonEnum.Succefull);
                }
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 获取功能列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetBaseSettingsItemTree()
        {
            var resp = new List<ResponseBaseSettingsItems>();
            var data = _baseSettingItem.GetList(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId)).ToList();
            var groupData = data.Select(f => f.GroupName).Distinct().ToList();
            foreach (var item in groupData)
            {
                var group = new ResponseBaseSettingsItems
                {
                    title = item
                };
                var children = _baseSettingItem.GetList(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId) && f.GroupName.Equals(item));
                foreach (var child in children)
                {
                    var respData = Mapper<SigerTrBaseSettingItem, ResponseBaseSettingsItems>.Map(child);
                    respData.disabled = false;
                    respData.title = respData.Descr;
                    group.Add(respData);
                }
                resp.Add(group);
            }
            return new ObjectResult(resp);
        }
        /// <summary>
        /// 保存工位功能设置
        /// </summary>
        /// <param name="section"></param>
        /// <param name="seq"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SaveBaseSettingData([FromBody]RequestSaveData requestSave)
        {
            var entities = _baseSetting.GetList(f => f.Station == requestSave.section && f.status != 0 && f.projectId == ProjectId).ToList();
            foreach(var entity in entities)
            {
                _baseSetting.Delete(entity);
            }
            if(string.IsNullOrEmpty(requestSave.seq))
            {
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
                throw new BadRequestException(CommonEnum.Fail);
            }
            var seqs = requestSave.seq.Split(',', StringSplitOptions.RemoveEmptyEntries);

            //var data = _baseSetting.Get(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId) && f.Seq == seq && f.Station == section);
            //if (data != null)
            //{
            //    return new ObjectResult(CommonEnum.Succefull);
            //}
            
            foreach (var strseqs in seqs)
            {
                var itemData = _baseSettingItem.Get(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId) && f.id == strseqs.ToInt());
                if (itemData == null)
                {
                    throw new BadRequestException(CommonEnum.Fail);
                }
                var newData = new SigerTrBaseSetting
                {
                    Station = requestSave.section,
                    GroupName = itemData.GroupName,
                    Seq = strseqs.ToInt(),
                    Item = itemData.Item,
                    TransDateTime = DateTime.Now,
                    UID = UserId.ToStr(),
                    projectId = ProjectId,
                    Value = ""
                };
                _baseSetting.Insert(newData);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除工位功能设置
        /// </summary>
        /// <param name="section"></param>
        /// <param name="seq"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteBaseSettingData(int section, int seq)
        {
            var data = _baseSetting.Get(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId) && f.Seq == seq && f.Station == section);
            if (data == null)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            _baseSetting.Delete(data);
            if (_unitOfWork.Commit() == 1)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 工位所有设置
        /// </summary>
        /// <param name="section"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetBaseSettings(int section)
        {
            var resp = new List<SigerTrBaseSetting>();
            resp = _baseSetting.GetList(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId) && f.Station == section).ToList();
            return new ObjectResult(resp);
        }
        /// <summary>
        /// 获取产线层级
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSectionTree()
        {
            var sections = _sigerProjectLevelSection.GetLevelSectionTree(ProjectId);
            var list = GetSection(sections);
            return new ObjectResult(list);
        }
        private List<LevelSectionTree> GetSection(IEnumerable<LevelSectionTree> models)
        {
            var father = models.Where(f => f.pid == 0).ToList();
            father.ForEach(data =>
            {
                data.children = GetChild(models, data.id);
            });
            return father;
        }
        private List<LevelSectionTree> GetChild(IEnumerable<LevelSectionTree> models, int parent)
        {
            var result = models.Where(f => f.pid.Equals(parent)).ToList();
            result.ForEach(data =>
            {
                var child = GetChild(models, data.id);
                if (!child.Any())
                {
                    data.disabled = false;
                }
                data.children = child;
            });
            return result;
        }
        /// <summary>
        /// 获取产线层级
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSectionData()
        {
            int parent = 0;
            var parentdata = _sigerProjectLevelSection.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.parentid == 0);
            if (parentdata != null)
            {
                parent = parentdata.id;
            }
            var data = _sigerProjectLevelSection.GetSectionData(ProjectId, parent);
            return new ObjectResult(data);
        }
    }
}