using DbCommon.BusinessCore.DbCore;
using DbCommon.Enties.DbModels;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DbCommon.BusinessCore.BaseCore
{
    public class LocationPropertyManager : DbContext<LocationProperty>
    {
        public DataTable QueryLocation(string wHouse)
        {
            return Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse)
                .ToDataTable();
        }

        public LocationProperty QueryData(string locationCode)
        {
            return Db.Queryable<LocationProperty>()
                .Where(d => d.LocationCode == locationCode)
                .First();
        }

        public List<LocationProperty> QueryDataList(string wHouse)
        {
            return Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse)
                .ToList();
        }

        public string QueryWareHouse(string locationCode)
        {
            return Db.Queryable<LocationProperty>()
                .Where(d => d.LocationCode == locationCode)
                .Select(f => f.WareHouseCode)
                .First();
        }

        public bool CheckLocation(LocationProperty data)
        {
            if (data == null) return false;
            //检查出库的线路上是否都是空状态（障碍检测）
            var location = Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == data.WareHouseCode
                    && d.Status != LocationStatus.Empty
                    && d.ColumnIndex == data.ColumnIndex
                    && d.RowIndex < data.RowIndex)
                .Select(f => f.LocationCode)
                .First();

            return string.IsNullOrEmpty(location);
        }

        public bool CheckLocation(string locationCode)
        {
            var data = Db.Queryable<LocationProperty>()
                .Where(d => d.LocationCode == locationCode)
                .First();

            if (data == null)
            {
                return false;
            }

            return CheckLocation(data);
        }

        public string QueryLocation_Out(string wHouse, LocationStatus status)
        {
            var locationList = Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse && d.Status == status)
                .OrderBy(d => d.ColumnIndex, SqlSugar.OrderByType.Asc)
                .OrderBy(d => d.RowIndex, SqlSugar.OrderByType.Asc)
                .ToList();

            return locationList.FirstOrDefault(d => CheckLocation(d))?.LocationCode;
        }

        public string QueryLocation_Out(string wHouse, LocationStatus status, string material)
        {
            var locationList = Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse && d.Status == status && d.MaterialId == material)
                .OrderBy(d => d.ColumnIndex, SqlSugar.OrderByType.Asc)
                .OrderBy(d => d.RowIndex, SqlSugar.OrderByType.Asc)
                .ToList();

            return locationList.FirstOrDefault(d => CheckLocation(d))?.LocationCode;
        }

        public List<LocationProperty> QueryLocation_Out_DataList(string wHouse, LocationStatus status)
        {
            var locationList = Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse && d.Status == status)
                .OrderBy(d => d.ColumnIndex, SqlSugar.OrderByType.Asc)
                .OrderBy(d => d.RowIndex, SqlSugar.OrderByType.Asc)
                .ToList();

            return locationList.Where(d => CheckLocation(d)).ToList();
        }

        public List<LocationProperty> QueryLocation_In_DataList(string wHouse, LocationStatus status)
        {
            var locationList = Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse && d.Status == status)
                .OrderBy(d => d.ColumnIndex, SqlSugar.OrderByType.Asc)
                .OrderBy(d => d.RowIndex, SqlSugar.OrderByType.Desc)
                .ToList();

            return locationList.Where(d => CheckLocation(d)).ToList();
        }

        public string QueryLocation_In(string wHouse, LocationStatus status)
        {
            var locationList = Db.Queryable<LocationProperty>()
                .Where(d => d.WareHouseCode == wHouse && d.Status == status)
                .OrderBy(d => d.ColumnIndex, SqlSugar.OrderByType.Asc)
                .OrderBy(d => d.RowIndex, SqlSugar.OrderByType.Desc)
                .ToList();

            return locationList.FirstOrDefault(d => CheckLocation(d))?.LocationCode;
        }


        public bool UpdateStatus(string locationCode, LocationStatus status)
        {
            string nowTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            return CurrentDb.Update(
                d => new LocationProperty()
                {
                    Status = status,
                    ModifyTime = nowTime
                },
                d => d.LocationCode == locationCode);
        }

        public bool UpdateStatusAndMaterial(string locationCode, LocationStatus status, string material)
        {
            string nowTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            return CurrentDb.Update(
                d => new LocationProperty()
                {
                    Status = status,
                    MaterialId = material,
                    ModifyTime = nowTime
                },
                d => d.LocationCode == locationCode);
        }

        public bool UpdateStatusAndStatusBackup(string locationCode, LocationStatus status, LocationStatus statusBackup)
        {
            string nowTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            return CurrentDb.Update(
                d => new LocationProperty()
                {
                    Status = status,
                    StatusBackup = ((int)statusBackup).ToString(),
                    ModifyTime = nowTime
                },
                d => d.LocationCode == locationCode);
        }

        public bool UpdateStatusNotLocked(string locationCode, LocationStatus status)
        {
            string nowTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            return CurrentDb.Update(
                d => new LocationProperty()
                {
                    Status = status,
                    ModifyTime = nowTime
                },
                d => d.LocationCode == locationCode
                && d.Status != LocationStatus.Locked);
        }

        public bool UpdateStatusMaterialNotLocked(string locationCode, LocationStatus status, string material)
        {
            string nowTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            return CurrentDb.Update(
                d => new LocationProperty()
                {
                    Status = status,
                    MaterialId = material,
                    ModifyTime = nowTime
                },
                d => d.LocationCode == locationCode
                && d.Status != LocationStatus.Locked);
        }
    }
}
