using System;
using System.Collections.Generic;
using System.Linq;
using Siger.ApiCommon.Exceptions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;

namespace Siger.ApiTPM.Utilities
{
    public class SparepartHelper
    {
        private readonly int _projectId;
        private readonly int _userId;
        private readonly ISparepartRecordRepository _sparepartRecordRepository;
        private readonly ISparepartRepository _sparepartRepository;
        public SparepartHelper(int projectId, int userId, ISparepartRecordRepository sparepartRecordRepository, ISparepartRepository sparepartRepository)
        {
            _projectId = projectId;
            _sparepartRecordRepository = sparepartRecordRepository;
            _sparepartRepository = sparepartRepository;
            _userId = userId;
        }

        /// <summary>
        /// 查询出入库备件名称*数量
        /// </summary>
        /// <returns></returns>
        public List<string> GetSparepartNameNum(string sparepartout)
        {
            var SparepartArr = new Dictionary<int, int>();
            var NameNumArr = new List<string>();
            if (!string.IsNullOrEmpty(sparepartout))
            {
                var spareparts = sparepartout.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (var spa in spareparts)
                {
                    var idcount = spa.Split('*', StringSplitOptions.RemoveEmptyEntries);
                    if (idcount.Any() && idcount.Length > 1 && idcount[0].ToInt() > 0 && idcount[1].ToInt() > 0)
                    {
                        if (SparepartArr.ContainsKey(idcount[0].ToInt()))
                        {
                            continue;
                        }
                        SparepartArr.Add(idcount[0].ToInt(), idcount[1].ToInt());
                        var sparepart = _sparepartRepository.Get(t => t.id == idcount[0].ToInt());
                        if(sparepart != null)
                        {
                            NameNumArr.Add(sparepart.title + "(" + sparepart.code + ")*" + idcount[1].ToInt());
                        }
                    }
                }
            }

            return NameNumArr;
        }

        /// <summary>
        /// id*数量
        /// </summary>
        /// <returns></returns>
        public List<string> GetSaprepartIdNum(string sparepartout)
        {
            var SparepartArr = new Dictionary<int, int>();
            var IdNumArr = new List<string>();
            if (!string.IsNullOrEmpty(sparepartout))
            {
                var spareparts = sparepartout.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (var spa in spareparts)
                {
                    var idcount = spa.Split('*', StringSplitOptions.RemoveEmptyEntries);
                    if (idcount.Any() && idcount.Length > 1 && idcount[0].ToInt() > 0 && idcount[1].ToInt() > 0)
                    {
                        if (SparepartArr.ContainsKey(idcount[0].ToInt()))
                        {
                            continue;
                        }
                        SparepartArr.Add(idcount[0].ToInt(), idcount[1].ToInt());
                        IdNumArr.Add(idcount[0].ToInt() + "*" + idcount[1].ToInt());
                    }
                }
            }
            return IdNumArr;
        }

        /// <summary>
        /// 查询出入库单号
        /// </summary>
        /// <returns></returns>
        public List<string> GetSparepartOutCode(string sparepartout, int repairId, int type)
        {
            var ids = new List<int>();
            if (!string.IsNullOrEmpty(sparepartout))
            {
                var idstr = sparepartout.Split(new[] { ',' });
                foreach (var p in idstr)
                {
                    if (!string.IsNullOrEmpty(p))
                    {
                        var spalist = p.Split('*', StringSplitOptions.RemoveEmptyEntries);
                        if (spalist.Length > 1)
                        {
                            ids.Add(spalist[0].ToInt());
                        }
                    }
                }
            }

            var query = _sparepartRecordRepository
                .GetListBySparepartOutType(ids, type, repairId.ToString(), _projectId)
                .ToList();
            var recordCodeArr = new List<string>();
            foreach (var p in query)
            {
                recordCodeArr.Add(p.record_code);
            }

            return recordCodeArr;
        }

        public void SparepartOutIn(Dictionary<int, int> oldSparepartArr, Dictionary<int, int> newSparepartArr,
            string repairId, int machineId, int IO_type)
        {
            if (oldSparepartArr.Any())
            {
                //入库修改后删除的备件
                foreach (var spa in oldSparepartArr)
                {
                    //入库不存在新备件数组中的数据
                    if (!newSparepartArr.ContainsKey(spa.Key))
                    {
                        OutSparepart(repairId, spa.Key, spa.Value, (int)StockCategory.OutStock, machineId, IO_type, 0, true);
                    }
                }
            }
            if (newSparepartArr.Any())
            {
                int i = 0;//插入数量
                foreach (var spa in newSparepartArr)
                {
                    //对添加的备件进行出库
                    if (!oldSparepartArr.ContainsKey(spa.Key))
                    {
                        OutSparepart(repairId, spa.Key, spa.Value, (int)StockCategory.OutStock, machineId,
                            IO_type, i, false);
                        i++;
                    }
                    else
                    {
                        //比较数量变化
                        if (spa.Value >= oldSparepartArr[spa.Key])
                        {
                            //数量变多 出库
                            OutSparepart(repairId, spa.Key, spa.Value, (int)StockCategory.OutStock, machineId, IO_type, i, false);
                            i++;
                        }
                        else if (spa.Value < oldSparepartArr[spa.Key])
                        {
                            //数量变少 入库
                            OutSparepart(repairId, spa.Key, spa.Value, (int)StockCategory.InStock, machineId, IO_type, i, false);
                            i++;
                        }
                    }
                }
            }
        }

        private void OutSparepart(string repairid, int sparepartid, int num, int type, int machineid, int IO_type, int insertNumber, bool isDelete)
        {
            var sparecord = _sparepartRecordRepository.Get(t => t.order_code == repairid && t.sparepartid == sparepartid && t.type == type
                && t.IO_type == IO_type && t.status == (int)RowState.Valid && t.projectid == _projectId);
            if (isDelete)
            {
                if (sparecord != null)
                {
                    sparecord.status = (int)RowState.Invalid;
                    _sparepartRecordRepository.Update(sparecord);
                }
            }
            else
            {
                bool isInsert = false;
                if (sparecord == null)
                {
                    isInsert = true;
                    sparecord = new siger_project_sparepart_record
                    {
                        number = num,
                        machineid = machineid,
                        order_code = repairid,
                        type = (int)StockCategory.OutStock,
                        IO_type = IO_type,
                        sparepartid = sparepartid,
                        relation_repair = 1,
                        create_mid = _userId,
                        operate_mid = _userId.ToString(),
                        create_time = UnixTimeHelper.GetNow(),
                        projectid = _projectId
                    };
                    var res1 = _sparepartRecordRepository.GetList(t => t.projectid == _projectId && t.type == type
                        && t.status == (int)RowState.Valid && !string.IsNullOrEmpty(t.record_code))
                        .OrderByDescending(t => t.id).ToList();
                    if (res1.Any())
                    {
                        var code = res1[0].record_code.Split('-', StringSplitOptions.RemoveEmptyEntries);
                        if (code.Count() > 1)
                        {
                            sparecord.record_code = code[0] + "-" + (code[1].ToInt() + 1 + insertNumber);
                        }
                    }
                    else
                    {
                        sparecord.record_code = type == (int)StockCategory.OutStock ? "C-1" : "R-1";
                    }
                }
                var sparepart = _sparepartRepository.Get(t => t.id == sparepartid && t.status == (int)RowState.Valid);
                var number = 0;
                if (sparepart != null)
                {
                    if (isInsert)
                    {
                        number = type == (int)StockCategory.OutStock ? sparepart.sku - num : num + sparepart.sku;
                    }
                    else
                    {
                        var addnum = type == (int)StockCategory.OutStock ? num - sparecord.number : sparecord.number - num;
                        number = type == (int)StockCategory.OutStock ? sparepart.sku - addnum : addnum + sparepart.sku;
                    }
                    sparepart.sku = number;
                    _sparepartRepository.Update(sparepart);

                    sparecord.price = sparepart.price;
                    sparecord.number = num;
                    sparecord.sum_price = num * sparepart.price;
                    sparecord.record_code = string.IsNullOrEmpty(sparecord.record_code) ? sparepart.code : sparecord.record_code;
                }
                sparecord.last_sku = number;
                sparecord.type = type;
                if (isInsert)
                {
                    _sparepartRecordRepository.Insert(sparecord);
                }
                else
                {
                    _sparepartRecordRepository.Update(sparecord);
                }
            }
        }

        public Dictionary<string, Dictionary<int, int>> CheckSparepart(string newSpareparts, string oldSpareparts)
        {
            #region 备件数量是否超过库存
            var oldSparepartArr = new Dictionary<int, int>();
            if (!string.IsNullOrEmpty(newSpareparts))
            {
                var oldspareparts = oldSpareparts.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (var spa in oldspareparts)
                {
                    var idcount = spa.Split('*', StringSplitOptions.RemoveEmptyEntries);
                    if (idcount.Any() && idcount.Length > 1 && idcount[0].ToInt() > 0 && idcount[1].ToInt() > 0)
                    {
                        if (oldSparepartArr.ContainsKey(idcount[0].ToInt()))
                        {
                            continue;
                        }
                        oldSparepartArr.Add(idcount[0].ToInt(), idcount[1].ToInt());
                    }
                }
            }
            var newSparepartArr = new Dictionary<int, int>();
            if (!string.IsNullOrEmpty(newSpareparts))
            {
                var new_spareparts = newSpareparts.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (var spa in new_spareparts)
                {
                    var idcount = spa.Split('*', StringSplitOptions.RemoveEmptyEntries);
                    if (idcount.Any() && idcount.Length > 1 && idcount[0].ToInt() > 0 && idcount[1].ToInt() > 0)
                    {
                        if (newSparepartArr.ContainsKey(idcount[0].ToInt()))
                        {
                            continue;
                        }
                        newSparepartArr.Add(idcount[0].ToInt(), idcount[1].ToInt());
                    }
                }
            }
            if (newSparepartArr.Any())
            {
                foreach (var p in newSparepartArr)
                {
                    var newsparepart = _sparepartRepository.Get(t =>
                        t.id == p.Key && t.status == (int) RowState.Valid && t.projectid == _projectId);
                    if (newsparepart != null && p.Value > newsparepart.sku)
                    {
                        if (oldSparepartArr.Any() && oldSparepartArr[p.Key] == p.Value)
                            continue;
                        throw new ServerException(300060);
                    }
                }
            }
            #endregion

            var res = new Dictionary<string, Dictionary<int, int>> {{"old", oldSparepartArr}, {"new", newSparepartArr}};
            return res;
        }
    }
}
