using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoTurnOver.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using AutoTurnOver.Utility;
using AutoTurnOver.Models.Report;
using System.Data;
using AutoTurnOver.Common;
using System.IO;
using AutoTurnOver.Models;

namespace AutoTurnOver.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class ReportsController : ControllerBase
    {
        /// <summary>ForecastSalePutinStockShort
        /// 获取预测销售+入库+库存+缺货数
        /// </summary>
        /// <param name="sku">sku编码</param>
        /// <param name="warehousecode">仓库编码</param>
        /// <returns></returns>
        public JsonResult ForecastSalePutinStockShort(string sku, string warehousecode)
        {
            var services = new Services.ReportServices();
            var result = services.ForecastSalePutinStockShort(sku, warehousecode);

            var count = 0;
            foreach (var item in result)
            {
                var arr = item.Split(',');

                if (arr.Length > 1)
                {
                    count = arr.Length;
                    break;
                }
            }
            //[0.13, 0.12, 0.11, 0.11, 0.1, 0.09, 0.09, 0.08, 0.08, 0.07, 0.06, 0.06, 0.05, 0.04, 0.04, 0.03, 0.02, 0.02, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
            var date = new List<string>();
            var today = DateTime.Now.AddDays(-7);

            for (var i = 0; i < count; i++)
            {
                date.Add(today.AddDays(i).ToString("MM/dd"));
            }

            var names = new List<string>() { "销量", "计算规则", "预计入库", "可用库存", "预计缺货数量", "特殊销量", "市场因素", "建议下单数量", "人工下单数量" };
            var turnoverData = new Services.SkuAutoTurnServices().GetModel(sku, warehousecode);
            var saleVolumeData = new Services.SaleVolumeServices().GetBySkuWarehouseCode(sku, warehousecode);
            var averageTargets = PurchaseAverageTargetServices.GetListByWCode(sku, warehousecode);
            var averageTargetWarehouse = PurchaseAverageTargetServices.GetWarehouse(sku, warehousecode);
            DateTime turnoverDate = DateTime.Now.AddDays(turnoverData.turnover_days);

            // 计算到周转期前一天的累计销量
            decimal turnoverDatecumulativeSales = 0;
            var salesList = result[0].ToObj<List<decimal>>();
            for (int i = 7; i < turnoverData.turnover_days + 7 - 1; i++)
            {
                turnoverDatecumulativeSales += salesList[i];
            }


            // 累计预计到货
            decimal turnoverDatepurchase = 0;
            var purchaseList = result[2].ToObj<List<decimal>>();
            for (int i = 7; i < turnoverData.turnover_days + 7; i++)
            {
                turnoverDatepurchase += purchaseList[i];
            }

            // 当日预测销量
            var turnoverDateSales = (int)result[0].ToObj<List<decimal>>()[turnoverData.turnover_days + 7 - 1];
            var buyFormula = new
            {
                turnoverDateStr = turnoverDate.ToString("yyyy-MM-dd"), // 取值日期
                turnoverDateSales = turnoverDateSales, // 当日预测销量
                turnoverDateStock = (int)result[3].ToObj<List<decimal>>()[turnoverData.turnover_days + 7 - 1],   // 当日预测库存,
                turnoverDatecumulativeSales = (int)turnoverDatecumulativeSales, // 累计销量
                nowStr = DateTime.Now.ToString("yyyy-MM-dd"), // 今天的日期
                nowShortage = (int)result[4].ToObj<List<decimal>>()[7], // 今天的实际缺货
                cumulativeShortageDate = turnoverDate.AddDays(-1).ToString("yyyy-MM-dd"),// 一直到周转期前一天的日期
                cumulativeShortage = (int)result[4].ToObj<List<decimal>>()[turnoverData.turnover_days + 7 - 1],  // 一直到周转期前一天的累计缺货
                average_overdue = Math.Max(0, turnoverData.average_overdue),
                nowDateStock = (int)result[3].ToObj<List<decimal>>()[7],   // 今天的预测库存
                turnoverDatepurchase = turnoverDatepurchase // 累计预计到货
            };
            return new JsonResult(new
            {
                data = result,
                turnoverData,
                saleVolumeData,
                days = date,
                names,
                averageTargets,
                averageTargetWarehouse,
                buyFormula
            }
            );
        }



        /// <summary>
        /// 实时库存
        /// </summary>
        /// <param name="sku"></param>
        /// <param name="warehousecode"></param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public JsonResult QuantityOutStockList(string bailun_sku, string warehousecode, string product_inner_code, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new quantity_out_stock_search_dto
            {
                bailun_sku = bailun_sku,
                isSum = false,
                product_inner_code = product_inner_code,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.QuantityOutStockList(m, offset, limit, ref total, order: order, sort: sort);

            return new JsonResult(new
            {
                rows = list,
                total = total,
            });
        }

        public JsonResult QuantityOutStockFooter(string bailun_sku, string warehousecode, string product_inner_code, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new quantity_out_stock_search_dto
            {
                bailun_sku = bailun_sku,
                isSum = true,
                product_inner_code = product_inner_code,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.QuantityOutStockList(m, offset, limit, ref total, order: order, sort: sort);

            return new JsonResult(list == null || list.Count <= 0 ? new quantity_out_stock_dto() : list[0]);
        }

        /// <summary>
        /// 导出实时缺货
        /// </summary>
        /// <param name="sku"></param>
        /// <param name="warehousecode"></param>
        /// <returns></returns>
        public FileResult QuantityOutStockExport(string bailun_sku, string warehousecode, string product_inner_code, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new quantity_out_stock_search_dto
            {
                bailun_sku = bailun_sku,
                product_inner_code = product_inner_code,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.QuantityOutStockList(m, 0, int.MaxValue, ref total, order: order, sort: sort);

            DataTable table = new DataTable();
            string[] cols = new string[] { "仓库编码", "仓库名称", "sku", "产品名称", "缺货总数量", "采购员", "缺货最后更新时间", "总在途","调拨在途最后更新时间","采购在途最后更新时间"
            };
            foreach (var item in cols)
            {
                table.Columns.Add(item);
            }

            foreach (var itemData in list)
            {
                DataRow row = table.NewRow();

                row["仓库编码"] = itemData.warehouse_code;
                row["仓库名称"] = itemData.warehouse_name;
                row["sku"] = itemData.bailun_sku;
                row["产品名称"] = itemData.sku_name;
                row["缺货总数量"] = itemData.quantity_out_stock;
                row["采购员"] = itemData.buyer_name;
                row["缺货最后更新时间"] = itemData.update_time;
                row["总在途"] = itemData.quantity_ontheway;
                row["调拨在途最后更新时间"] = itemData.gmt_transfer_modified;
                row["采购在途最后更新时间"] = itemData.gmt_purchase_modified;

                table.Rows.Add(row);
            }

            var fileName = AppContext.BaseDirectory + @"Result\RealtimeStock\实时缺货数据.csv";

            DataTableHelper.SaveCSV(table, fileName);

            var memory = new MemoryStream();
            using (var stream = new FileStream(fileName, FileMode.Open))
            {
                stream.CopyTo(memory);
            }
            memory.Position = 0;
            return File(memory, "text/csv", "实时缺货数据.csv");
        }





        /// <summary>
        /// 实时库存
        /// </summary>
        /// <param name="sku"></param>
        /// <param name="warehousecode"></param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public JsonResult QuantityOutStockDetailList(DateTime? pay_time_min,DateTime? pay_time_max,string platform_type,string shiplogistics_code,  int? bailun_account_id, int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new quantity_out_stock_detail_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode,
                bailun_account_id = bailun_account_id,
                shiplogistics_code = shiplogistics_code,
                platform_type = platform_type,
                pay_time_max = pay_time_max,
                pay_time_min = pay_time_min
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.QuantityOutStockDetailList(m, offset, limit, ref total, order: order, sort: sort);

            return new JsonResult(new
            {
                rows = list,
                total = total,
            });
        }


        public JsonResult QuantityOutStockDetailFooter(DateTime? pay_time_min, DateTime? pay_time_max, string platform_type, string shiplogistics_code, int? bailun_account_id, int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new quantity_out_stock_detail_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                isSum = true,
                warehousetype = warehousetype,
                warehouse_code = warehousecode,
                bailun_account_id = bailun_account_id,
                shiplogistics_code = shiplogistics_code,
                platform_type = platform_type,
                pay_time_max = pay_time_max,
                pay_time_min = pay_time_min
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.QuantityOutStockDetailList(m, offset, limit, ref total, order: order, sort: sort);

            return new JsonResult(list == null || list.Count <= 0 ? new quantity_out_stock_detail_dto() : list[0]);
        }

       
        public FileResult QuantityOutStockDetailExport(DateTime? pay_time_min, DateTime? pay_time_max, string platform_type, string shiplogistics_code, int? bailun_account_id, int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new quantity_out_stock_detail_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode,
                bailun_account_id = bailun_account_id,
                shiplogistics_code = shiplogistics_code,
                platform_type = platform_type,
                pay_time_max = pay_time_max,
                pay_time_min = pay_time_min
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.QuantityOutStockDetailList(m, 0, int.MaxValue, ref total, order: order, sort: sort);
            // Detail
            DataTable table = new DataTable();
            string[] cols = new string[] { "缺货统计时间", "平台订单号", "平台类型", "百伦订单号", "付款交易号", "站点", "付款时间", "销售账号","国家","sku","订单所有itemid",
                "产品名称", "订单sku销量", "发货数量","发货仓库编码","发货仓库", "是否缺货", "仓库总缺货", "国内仓总缺货", "其他有库存仓库", "其他仓库库存数","国内仓是否缺货","采购员",
                 "平台物流方式", "发货物流方式", "sku监控状态", "销售状态", "总在途库存数", "最先到货采购单","最快到货时间","采购单供应商","采购单阿里巴巴单号","采购单物流单号"
            };
            foreach (var item in cols)
            {
                table.Columns.Add(item);
            }

            foreach (var itemData in list)
            {
                DataRow row = table.NewRow();

                row["缺货统计时间"] = itemData.gmt_out_stock_modified==null?"": itemData.gmt_out_stock_modified.Value.ToString("yyyy-MM-dd HH:mm:ss");
                row["平台订单号"] = itemData.origin_order_id;
                row["平台类型"] = itemData.platform_type;
                row["百伦订单号"] = itemData.bailun_order_id;
                row["付款交易号"] = itemData.transaction_id;
                row["站点"] = itemData.website;
                row["付款时间"] = itemData.pay_time == null ? "" : itemData.pay_time.Value.ToString("yyyy-MM-dd HH:mm:ss");
                row["销售账号"] = itemData.seller_account;
                row["国家"] = itemData.receipt_country;
                row["sku"] = itemData.bailun_sku;
                row["订单所有itemid"] = itemData.items;
                row["产品名称"] = itemData.sku_name;
                row["订单sku销量"] = itemData.bailun_sku_quantity_ordered;
                row["发货数量"] = itemData.bailun_sku_quantity_shipped;
                row["发货仓库编码"] = itemData.warehouse_code;
                row["发货仓库"] = itemData.warehouse_name;
                row["是否缺货"] = itemData.is_out_stock;
                row["仓库总缺货"] = itemData.quantity_out_stock;
                row["国内仓总缺货"] = itemData.sum_quantity_out_stock;
                row["其他有库存仓库"] = itemData.other_codes;
                row["其他仓库库存数"] = itemData.other_stock;
                row["国内仓是否缺货"] = itemData.is_sum_quantity_out_stock;
                row["采购员"] = itemData.buyer_name;
                row["平台物流方式"] = itemData.bailun_require_logistics;
                row["发货物流方式"] = itemData.logistics_method_name;
                row["sku监控状态"] = itemData.monitor_status;
                row["销售状态"] = itemData.sku_status;
                row["总在途库存数"] = itemData.quantity_ontheway;
                row["最先到货采购单"] = itemData.min_buy.no;
                row["最快到货时间"] = itemData.min_buy.arrival_date.ToString("yyyy-MM-dd HH:mm:ss");
                row["采购单供应商"] = itemData.min_buy.supplier_name;
                row["采购单阿里巴巴单号"] = itemData.min_buy.alibaba_order_id;
                row["采购单物流单号"] = itemData.min_buy.logistics_order_id;

                table.Rows.Add(row);
            }

            var fileName = AppContext.BaseDirectory + @"Result\RealtimeStock\实时缺货明细数据.csv";

            DataTableHelper.SaveCSV(table, fileName);

            var memory = new MemoryStream();
            using (var stream = new FileStream(fileName, FileMode.Open))
            {
                stream.CopyTo(memory);
            }
            memory.Position = 0;
            return File(memory, "text/csv", "实时缺货明细数据.csv");
        }


        /// <summary>
        /// 缺货改0
        /// </summary>
        /// <param name="bailun_sku"></param>
        /// <param name="warehousecode"></param>
        /// <param name="product_inner_code"></param>
        /// <param name="purchase_user"></param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <param name="order"></param>
        /// <param name="sort"></param>
        /// <param name="warehousetype"></param>
        /// <param name="warehousearea"></param>
        /// <returns></returns>
        public JsonResult OutStockList(int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new out_stock_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.OutStockList(m, offset, limit, ref total, order: order, sort: sort);

            return new JsonResult(new
            {
                rows = list,
                total = total,
            });
        }

        /// <summary>
        /// 导出缺货改0数据
        /// </summary>
        /// <param name="sku"></param>
        /// <param name="warehousecode"></param>
        /// <returns></returns>
        public FileResult OutStockExport(int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new out_stock_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.OutStockList(m, 0, int.MaxValue, ref total, order: order, sort: sort);
            // Detail
            DataTable table = new DataTable();
            string[] cols = new string[] { "商品编码", "仓库编码", "仓库名称", "sku", "产品名称", "缺货总数量", "sku监控状态", "采购员","平台物流方式","发货物流方式"
            };
            foreach (var item in cols)
            {
                table.Columns.Add(item);
            }

            foreach (var itemData in list)
            {
                DataRow row = table.NewRow();

                row["商品编码"] = itemData.product_code;
                row["仓库编码"] = itemData.warehouse_code;
                row["仓库名称"] = itemData.warehouse_name;
                row["sku"] = itemData.bailun_sku;
                row["产品名称"] = itemData.sku_name;
                row["缺货总数量"] = itemData.sum_quantity_out_stock;
                row["采购员"] = itemData.buyer_name;
                row["平台物流方式"] = itemData.ebay_bailun_require_logistics;
                row["发货物流方式"] = itemData.ebay_logistics_method_name;


                table.Rows.Add(row);
            }

            var fileName = AppContext.BaseDirectory + @"Result\RealtimeStock\缺货改0数据.csv";

            DataTableHelper.SaveCSV(table, fileName);

            var memory = new MemoryStream();
            using (var stream = new FileStream(fileName, FileMode.Open))
            {
                stream.CopyTo(memory);
            }
            memory.Position = 0;
            return File(memory, "text/csv", "缺货改0数据.csv");
        }

        /// <summary>
        /// 缺货改0
        /// </summary>
        /// <param name="bailun_sku"></param>
        /// <param name="warehousecode"></param>
        /// <param name="product_inner_code"></param>
        /// <param name="purchase_user"></param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <param name="order"></param>
        /// <param name="sort"></param>
        /// <param name="warehousetype"></param>
        /// <param name="warehousearea"></param>
        /// <returns></returns>
        public JsonResult ReturnSpeedChangeList(bool? has_available_stock, int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new return_speed_change_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode,
                has_available_stock = has_available_stock
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.ReturnSpeedChange(m, offset, limit, ref total, order: order, sort: sort);

            return new JsonResult(new
            {
                rows = list,
                total = total,
            });
        }

        /// <summary>
        /// 回货速补
        /// </summary>
        /// <param name="sku"></param>
        /// <param name="warehousecode"></param>
        /// <returns></returns>
        public FileResult ReturnSpeedChangeExport(bool? has_available_stock, int? search_type, string warehousecode, string key_words, string purchase_user, int offset, int limit, string order, string sort, string warehousetype, int? warehousearea)
        {
            var m = new return_speed_change_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode,
                has_available_stock = has_available_stock
            };
            var services = new ReportServices();
            var total = 0;
            var list = services.ReturnSpeedChange(m, 0, int.MaxValue, ref total, order: order, sort: sort);
            // Detail
            DataTable table = new DataTable();
            string[] cols = new string[] { "商品编码", "仓库编码", "仓库名称", "sku", "产品名称", "是否有可用库存", "sku监控状态", "采购员","平台物流方式","发货物流方式"
            };
            foreach (var item in cols)
            {
                table.Columns.Add(item);
            }

            foreach (var itemData in list)
            {
                DataRow row = table.NewRow();

                row["商品编码"] = itemData.product_code;
                row["仓库编码"] = itemData.warehouse_code;
                row["仓库名称"] = itemData.warehouse_name;
                row["sku"] = itemData.bailun_sku;
                row["产品名称"] = itemData.sku_name;
                row["是否有可用库存"] = itemData.has_available_stock == 1 ? "有" : "无";
                row["采购员"] = itemData.buyer_name;
                row["平台物流方式"] = itemData.ebay_bailun_require_logistics;
                row["发货物流方式"] = itemData.ebay_logistics_method_name;


                table.Rows.Add(row);
            }

            var fileName = AppContext.BaseDirectory + @"Result\RealtimeStock\回货速补数据.csv";

            DataTableHelper.SaveCSV(table, fileName);

            var memory = new MemoryStream();
            using (var stream = new FileStream(fileName, FileMode.Open))
            {
                stream.CopyTo(memory);
            }
            memory.Position = 0;
            return File(memory, "text/csv", "回货速补数据.csv");
        }

        /// <summary>
        /// 标记回货
        /// </summary>
        /// <param name="has_available_stock"></param>
        /// <param name="search_type"></param>
        /// <param name="warehousecode"></param>
        /// <param name="key_words"></param>
        /// <param name="purchase_user"></param>
        /// <param name="warehousetype"></param>
        /// <param name="warehousearea"></param>
        /// <returns></returns>
        public JsonResult MarkReturnSpeedChange(bool? has_available_stock, int? search_type, string warehousecode, string key_words, string purchase_user, string warehousetype, int? warehousearea)
        {
            var m = new return_speed_change_search_dto
            {
                search_type = search_type,
                key_words = key_words,
                purchase_user = purchase_user,
                warehousearea = warehousearea,
                warehousetype = warehousetype,
                warehouse_code = warehousecode,
                has_available_stock = has_available_stock
            };
            try
            {
                var services = new ReportServices();
                var total = services.MarkReturnSpeedChange(m);
                return new JsonResult(new { success = true, data = total });
            }
            catch (Exception ex)
            {
                return new JsonResult(new { success = false, message = ex.Message });
            }
        }

        /// <summary>
        /// 批量出信
        /// </summary>
        /// <returns></returns>
        public FileResult BatchSendMessage(string bailun_order_ids,string content,string subject,string remarks)
        {
            BatchSendMessageInputDto data = new BatchSendMessageInputDto {
                bailun_order_ids = bailun_order_ids,
                content = content,
                remarks = remarks,
                subject = subject
            };
            var services = new ReportServices();
            var table = services.BatchSendMessage(data);
            var fileName = $"出信结果.csv";
            var fullFileName = AppContext.BaseDirectory + $@"Result\SendMessage\{fileName}";
            DataTableHelper.SaveCSV(table, fullFileName);

            var memory = new MemoryStream();
            using (var stream = new FileStream(fullFileName, FileMode.Open))
            {
                stream.CopyTo(memory);
            }
            memory.Position = 0;
            return File(memory, "text/csv", "出信结果.csv");
        }
    }
}