using AutoTurnOver.DB;
using AutoTurnOver.Models;
using AutoTurnOver.Models.ApiDto;
using Bailun.ServiceFabric.Core;
using Dapper;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;

namespace AutoTurnOver.Services
{
    public class PurchaseAdviseServices
    {
        /// <summary>
        /// 创建采购计划
        /// </summary>
        public static void Generate()
        {
            try
            {
                // 创建一个采购计划
                var mainID = purchase_advise.Add(new dc_auto_purchase_advise { create_time = DateTime.Now, no = purchase_advise.GenerateOrderNo() ,buy_sys_plan_no = "Generate" });
                if (mainID == null) throw new Exception("创建采购建议失败");

                purchase_advise.ImportDetailed(mainID.Value);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        /// <summary>
        /// 获取采购建议列表
        /// </summary>
        /// <param name="m"></param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public static List<dc_auto_purchase_advise> List(dc_auto_purchase_advise_search_dto m, int offset, int limit, ref int total)
        {
            return purchase_advise.List(m, offset, limit, ref total);
        }

        /// <summary>
        /// 获取采购建议明细列表
        /// </summary>
        /// <param name="m"></param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public static List<dc_auto_purchase_advise_detailed_dto> DetailList(dc_auto_purchase_advise_detailed_search_dto m, int offset, int limit, ref int total, string order = "", string sort = "")
        {
            return purchase_advise.DetailList(m, offset, limit, ref total, order, sort);
        }

        /// <summary>
        /// 设置采购数量
        /// </summary>
        /// <param name="id"></param>
        public static void SetQuantityActual(int id, int quantity_actual)
        {
            purchase_advise.SetQuantityActual(id, quantity_actual);
        }

        /// <summary>
        /// 批量设置采购数量
        /// </summary>
        /// <param name="id"></param>
        public static void BatchSetQuantityActual(List<BatchSetQuantityActualInputDto> datas)
        {
            purchase_advise.BatchSetQuantityActual(datas);
        }


        /// <summary>
        /// 查询历史采购建议
        /// </summary>
        /// <param name="id"></param>
        public static dc_auto_purchase_advise_detailed DetailInfo(string sku, string warehousecode, DateTime dateTime)
        {
            return purchase_advise.DetailInfo(sku, warehousecode, dateTime);
        }



        public static void Del(int id)
        {
            purchase_advise.Del(id);
        }

        private static object _push_lock = new object();
        /// <summary>
        /// 把最新一批的采购单推送到采购系统
        /// </summary>
        /// <param name="datas"></param>
        /// <param name="user"></param>
        /// <param name="is_skip_error">是否跳过异常</param>
        public static void PushBuySys(List<dc_auto_purchase_advise_detailed_dto> datas, UserData user,bool is_skip_error,string remarks = "")
        {
            lock (_push_lock)
            {
                try
                {
                    //查询最近一个采购建议
                    // 
                    if (datas == null)
                    {
                        return;
                    }
                    List<string> planNos = new List<string>();
                    DateTime now = DateTime.Now;
                    // 查询未推送成功的采购建议的明细
                    var detailList = purchase_advise.BuyDetailList(datas.Select(s => s.id).ToList(), false);
                    foreach (var item in detailList.GroupBy(s => new { s.warehouse_code, s.warehouse_type,s.area_name }))
                    {

                        mPlanToPurchaseDto data = new mPlanToPurchaseDto
                        {
                            bp_send = item.Key.warehouse_type != "国内仓" ? 1 : 0,
                            bp_sendfromCode = item.Key.warehouse_type != "国内仓" ? "GZBLZZG" : item.Key.warehouse_code,
                            bp_sendtoCode = item.Key.warehouse_type != "国内仓" ? item.Key.warehouse_code : null,
                            sys_source = item.Any(s => s.type == 2) ? 2 : item.Any(s => s.type == 1) ? 1 : 3,
                            bi_buyplandetail = new List<bi_buyplandetail>(),
                            bp_remark = $"用户{user.UserName} 在 aims 操作推送-"+ remarks
                        };
                        data.bp_sendtype = data.bp_send == 1 ? 4 : -1;
                        if ("FBA仓".Equals(item.Key.warehouse_type,StringComparison.OrdinalIgnoreCase))
                        {
                            if("美国".Equals(item.Key.area_name, StringComparison.OrdinalIgnoreCase))
                            {
                                data.bp_sendtype = 2;
                            }else if ("英国".Equals(item.Key.area_name, StringComparison.OrdinalIgnoreCase)
                                || "法国".Equals(item.Key.area_name, StringComparison.OrdinalIgnoreCase)
                                || "德国".Equals(item.Key.area_name, StringComparison.OrdinalIgnoreCase)
                                || "意大利".Equals(item.Key.area_name, StringComparison.OrdinalIgnoreCase)
                                || "西班牙".Equals(item.Key.area_name, StringComparison.OrdinalIgnoreCase)
                                )
                            {
                                data.bp_sendtype = 4;
                            }
                        }

                        var sendtype = item.Max(s => s.sendtype);
                        if (sendtype > 0)
                        {
                            data.bp_sendtype = sendtype.Value;
                        }

                        data.bi_buyplandetail = item.GroupBy(s=>s.bailun_sku).Select(s => new bi_buyplandetail
                        {
                            bd_count = s.Sum(g=> g.quantity_actual > 0 ? g.quantity_actual : g.quantity_final_advise),
                            bd_price = s.Max(g=>g.unit_price),
                            bd_sku = s.Key,
                            sys_source = s.Any(g => g.type == 2) ? 2 : s.Any(g => g.type == 1) ? 1 : 3,
                        }).ToList();

                        var result = ApiServices.PushBuyPlan(data, is_skip_error);
                        if (result.IsSuccessed)
                        {
                            //把采购数量没有填的都补上 建议采购数
                            var sql = " update dc_auto_purchase_advise_detailed set quantity_actual=quantity_final_advise where quantity_actual<=0 and id in @ids ";
                            DynamicParameters parameters = new DynamicParameters();
                            parameters.Add("ids", item.Select(s => s.id).ToList());
                            if(result.fail_skus!=null && result.fail_skus.Count >= 1)
                            {
                                sql += " and bailun_sku not in @bailunSku ";
                                parameters.Add("bailunSku", result.fail_skus.ToList());
                            }
                            connectionHelper._connection.Execute(sql, parameters);

                            // 把相关的采购明细都标记成已推送
                            var sql2 = " update  dc_auto_purchase_advise_detailed set ispush=1,plan_nos=@plan_nos,push_user_name=@push_user_name where id in @ids ";
                            DynamicParameters parameters2 = new DynamicParameters();
                            parameters2.Add("ids", item.Select(s => s.id).ToArray());
                            parameters2.Add("plan_nos", result.planNo);
                            parameters2.Add("push_user_name", user.UserName);
                            if (result.fail_skus != null && result.fail_skus.Count >= 1)
                            {
                                sql2 += " and bailun_sku not in @bailunSku ";
                                parameters2.Add("bailunSku", result.fail_skus.ToList());
                            }
                            connectionHelper._connection.Execute(sql2, parameters2);
                        }
                        planNos.Add(result.planNo);

                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }

        }


        /// <summary>
        /// 速卖通的挑出来单独下
        /// </summary>
        public static void PushBuySysSplit_bak(List<dc_auto_purchase_advise_detailed_dto> datas, UserData user, bool is_skip_error)
        {
            if (datas == null || datas.Count <= 0) return;
            var amazon_datas = new List<dc_auto_purchase_advise_detailed_dto>();
            var ali_datas = new List<dc_auto_purchase_advise_detailed_dto>();
            var other_datas = new List<dc_auto_purchase_advise_detailed_dto>();

            foreach (var item in datas)
            {
                if("张莹霞".Equals(item.buyer_name))
                {
                    if (item.quantity_out_stock_other > 0)
                    {
                        var temp_other_data = item.ToJson().ToObject<dc_auto_purchase_advise_detailed_dto>();
                        temp_other_data.quantity_final_advise = Math.Min((int)item.quantity_out_stock_other, item.quantity_final_advise);
                        if (temp_other_data.quantity_final_advise > 0)
                        {
                            other_datas.Add(temp_other_data);
                            item.quantity_final_advise = Math.Max(0, (int)item.quantity_final_advise - temp_other_data.quantity_final_advise);
                        }
                    }

                    if (item.quantity_final_advise > 0 && item.quantity_out_stock_amazon > 0)
                    {
                        var temp_amazon_data = item.ToJson().ToObject<dc_auto_purchase_advise_detailed_dto>();
                        temp_amazon_data.quantity_final_advise =Math.Min( (int)item.quantity_out_stock_amazon.Value, item.quantity_final_advise);
                        if (temp_amazon_data.quantity_final_advise > 0)
                        {
                            amazon_datas.Add(temp_amazon_data);
                            item.quantity_final_advise = Math.Max(0, (int)item.quantity_final_advise - temp_amazon_data.quantity_final_advise);
                        }
                    }

                    if (item.quantity_final_advise > 0)
                    {
                        ali_datas.Add(item);
                    }
                }
                else
                {
                    ali_datas.Add(item);
                }
            }

            if (amazon_datas != null && amazon_datas.Count > 0)
            {
                PushBuySys(amazon_datas, user, is_skip_error, "亚马逊");
            }
            if (ali_datas!=null && ali_datas.Count > 0)
            {
                PushBuySys(ali_datas, user, is_skip_error,"速卖通");
            }
            if (other_datas != null && other_datas.Count > 0)
            {
                PushBuySys(other_datas, user, is_skip_error,"其他");
            }
                
        }


        /// <summary>
        /// 指定平台（ebay, wish）的挑出来单独下
        /// </summary>
        public static void PushBuySysSplit(List<dc_auto_purchase_advise_detailed_dto> datas, UserData user, bool is_skip_error)
        {
            if (datas == null || datas.Count <= 0) return;
            var alone_datas = new List<dc_auto_purchase_advise_detailed_dto>();
            var other_datas = new List<dc_auto_purchase_advise_detailed_dto>();

            // 查询当前有缺货的sku
            var shortageSkuList = purchase_advise.ShortageSkuList(new List<string> { "ebay","wish"},new List<string> { "张莹霞" });
            alone_datas = datas.Where(s => shortageSkuList.Any(v => v == s.bailun_sku)).ToList();
            other_datas = datas.Where(s => !shortageSkuList.Any(v => v == s.bailun_sku)).ToList();

            if (alone_datas != null && alone_datas.Count > 0)
            {
                PushBuySys(alone_datas, user, is_skip_error,"ebay+wish");
            }
            if (other_datas != null && other_datas.Count > 0)
            {
                PushBuySys(other_datas, user, is_skip_error,"其他");
            }
                
        }

        /// <summary>
        /// 自动推送采购单
        /// </summary>
        /// <param name="type">1：张莹霞  2：赵美聪 3:陈嘉雯1 </param>
        public static void AutoPushBuySys(int type)
        {
            try
            {
                // 生产jit采购建议
                var mainID = 0;
                if (type == 1)
                {
                    mainID = purchase_advise.ImportJITShortageDetailed(0);
                }
                else if (type == 2)
                {
                    mainID = purchase_advise.ImportFuZhuangShortageDetailed(0);
                }
                else if (type == 3)
                {
                    mainID = purchase_advise.ImportShoujiShortageDetailed(0);
                }else if(type==4)
                {
                    mainID = purchase_advise.ImportJITShortageDetailed1(0); 
                }
                else if (type == 5)
                {
                    mainID = purchase_advise.ImportFuZhuangShortageIncreaseDetailed(0);
                }
                else if (type == 6)
                {
                    mainID = purchase_advise.ImportYiWuShortageDetailed(0);
                }
                else if (type == 7)
                {
                    mainID = purchase_advise.ImportDuLiShortageDetailed(0);
                }
                List<dc_auto_purchase_advise_detailed_dto> datas = new List<dc_auto_purchase_advise_detailed_dto>();

                var total = 0;
                datas.AddRange(PurchaseAdviseServices.DetailList(new dc_auto_purchase_advise_detailed_search_dto { main_id = mainID,  ispush = false }, 0, int.MaxValue, ref total));
                //datas.AddRange(PurchaseAdviseServices.DetailList(new dc_auto_purchase_advise_detailed_search_dto { main_id = mainID,  ispush = false }, 0, int.MaxValue, ref total));
                if (true)
                {
                    PurchaseAdviseServices.PushBuySysSplit(datas, new UserData { UserName = "admin" }, true);
                }
                else
                {
                    PurchaseAdviseServices.PushBuySys(datas, new UserData { UserName = "admin" }, true);
                }
                
            }
            catch (Exception ex)
            {
               
                report.AddError(new dc_task_error_log
                {
                    date = DateTime.Now,
                    message = ex.Message,
                    stack_trace = ex.StackTrace,
                    task_name = "AutoPushBuySys"
                });
                Console.WriteLine(ex.Message);
                ApiServices.QiYeJiQiRenMsPush(new QiYeJiQiRenMsDto { msgtype = "text",text = new QiYeJiQiRenMsDto.text_dto { content = " 海丽，aims 采购单推送失败，请手动推送 "} });
                ApiServices.QiYeJiQiRenMsPush(new QiYeJiQiRenMsDto { msgtype = "text", text = new QiYeJiQiRenMsDto.text_dto { content = " 泽锋，查收异常消息： "+ex.Message } });
            }

        }

        /// <summary>
        /// 提取sku
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static List<string> ExtractSku(string message)
        {
            if (!message.Contains("SKU") && !message.Contains("sku"))
            {
                return null;
            }
            else
            {
                Regex skuRegex = new Regex(@"【[\s\S]+】");
                var skus = skuRegex.Matches(message);
                if (skus != null && skus.Count == 1)
                {
                    return skus[0].Value.Split(',').ToList();
                }
                else if (skus.Count > 1)
                {
                    report.AddError(new dc_task_error_log
                    {
                        date = DateTime.Now,
                        message = "异常中包含多个【】，识别异常",
                        stack_trace = message,
                        task_name = "AutoPushBuySys_ExtractSku"
                    });
                    return null;
                }
                else
                {
                    return null;
                }
            }
        }
    }
}
