namespace Tiobon.Core.Services;

/// <summary>
/// 学分记录 (服务)
/// </summary>
public class Ghre_CreditPointServices : BaseServices<Ghre_CreditPoint, Ghre_CreditPointDto, InsertGhre_CreditPointInput, EditGhre_CreditPointInput>, IGhre_CreditPointServices
{
    private readonly IBaseRepository<Ghre_CreditPoint> _dal;
    public Ghre_CreditPointServices(ICaching caching, IBaseRepository<Ghre_CreditPoint> dal)
    {
        this._dal = dal;
        base.BaseDal = dal;
        base._caching = caching;
    }

    public async Task<ServicePageResult<Ghre_CreditPointTotal>> QueryTotal(QueryBody filter,string condition)
    {
        RefAsync<int> totalCount = 0;
        string sql = @"SELECT *
                    FROM (SELECT StaffId Id,
                                 StaffNo,
                                 StaffName + ' (' + StaffNo + ')' StaffName,
                                 DeptNo,
                                 DepteName,
                                 TitleName,
                                 CONVERT (NVARCHAR (10), Indate, 120) Indate,
                                 InStatusLabel,
                                 DeptID,
                                 TitleID,
                                 SUM (CreditPoints) CreditPoints
                          FROM Ghre_CreditPoint_V
                          WHERE {0} 
                          GROUP BY StaffId,
                                   StaffNo,
                                   StaffName,
                                   DeptNo,
                                   DepteName,
                                   TitleName,
                                   Indate,
                                   InStatusLabel,
                                   DeptID,
                                   TitleID) A";

        if (string.IsNullOrWhiteSpace(filter.orderBy))
            filter.orderBy = "StaffNo ASC";

        string conditions = "1=1";
        if (filter.jsonParam != null)
            foreach (JProperty jProperty in filter.jsonParam.Properties())
            {
                var name = jProperty.Name;
                var value = jProperty.Value.ToString();
                if (name == "page" || name == "pageSize")
                    continue;

                //if (name == "Indate")
                //{
                //    var jsonParam = JsonConvert.DeserializeObject<JsonParam1>(value);
                //    conditions += $" AND (Indate BETWEEN '{jsonParam.columnValue[0]}' AND '{jsonParam.columnValue[1]}')";

                //    continue;
                //}
                if (name == "Date")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam1>(value);
                    conditions += $" AND (Date BETWEEN '{jsonParam.columnValue[0]}' AND '{jsonParam.columnValue[1]}')";

                    continue;
                }
                if (name == "CreditPoints")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                    switch (jsonParam.operationKey)
                    {
                        case "Include":
                            sql += $" WHERE {name} LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "NotInclude":
                            sql += $" WHERE {name} NOT LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "IsNull":
                            sql += $" WHERE {name} IS NULL";
                            break;
                        case "NotNull":
                            sql += $" WHERE {name} IS NOT NULL";
                            break;
                        case "Equal":
                            sql += $" WHERE {name} ='{jsonParam.columnValue}'";
                            break;
                        case "NotEqual":
                            sql += $" WHERE {name} !='{jsonParam.columnValue}'";
                            break;
                        case "GreaterOrEqual"://大于等于
                            sql += $" WHERE {name} >='{jsonParam.columnValue}'";
                            break;
                        case "Greater"://大于
                            sql += $" WHERE {name} >'{jsonParam.columnValue}'";
                            break;
                        case "LessOrEqual"://小于等于
                            sql += $" WHERE {name} <='{jsonParam.columnValue}'";
                            break;
                        case "Less"://小于
                            sql += $" WHERE {name} <'{jsonParam.columnValue}'";
                            break;
                        default:
                            break;
                    }

                    continue;
                }

                if (!string.IsNullOrWhiteSpace(value))
                    conditions = DealConditions(conditions, name, value);
            }

        //if (ids != null && ids.Any())
        //    conditions += $" AND Id IN({string.Join(",", ids)})";
        if (!condition.IsNull())
            conditions += " AND " + condition;
        conditions += $" AND dbo.FUserDataBelongPriv ({App.User.ID}, DataBelongID, NULL) = 1";

        if (await Db.Queryable<Ghrs_Menu>().Where(x => x.DataPrivType == "Priv" && x.MenuNo == filter.menuName).AnyAsync())
        {
            var staffIds = await GetUserStaffPrivIds((int)App.User.ID);
            if (staffIds.Any())
                conditions += $" AND StaffId IN ({string.Join(",", staffIds.Select(id => "'" + id + "'"))})";
        }

        sql = string.Format(sql, conditions);
        if (filter.pageSize == 0)
            filter.pageSize = 10000;
        var data = await Db.SqlQueryable<Ghre_CreditPointTotal>(sql)
            .OrderBy(filter.orderBy)
            .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount);

        return new ServicePageResult<Ghre_CreditPointTotal>(filter.pageNum, totalCount, filter.pageSize, data);
    }


    public async Task<ServicePageResult<Ghre_CreditPointDetail>> QueryDetail(QueryBody filter, string staffId)
    {
        RefAsync<int> totalCount = 0;
        string sql = @$"SELECT A.Id,
                           CONVERT (VARCHAR (100), A.[Date], 23) Date,
                            A.[Date] Date1,
                           A.CreditPoints,
                           B.CoverUrl,
                           B.CourseClass,
                           B.CourseScene,
                           B.CourseNo,
                           B.CourseName
                    FROM Ghre_CreditPoint A LEFT JOIN Ghre_CourseSnap B ON A.CourseSnapId = B.Id
                    WHERE A.StaffId = '{staffId}'";

        if (string.IsNullOrWhiteSpace(filter.orderBy))
            filter.orderBy = "Date1 DESC";

        string conditions = "1=1";
        if (filter.jsonParam != null)
            foreach (JProperty jProperty in filter.jsonParam.Properties())
            {
                var name = jProperty.Name;
                var value = jProperty.Value.ToString();
                if (name == "page" || name == "pageSize")
                    continue;

                //if (name == "Indate")
                //{
                //    var jsonParam = JsonConvert.DeserializeObject<JsonParam1>(value);
                //    conditions += $" AND (Indate BETWEEN '{jsonParam.columnValue[0]}' AND '{jsonParam.columnValue[1]}')";

                //    continue;
                //}
                if (name == "Date")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam1>(value);
                    conditions += $" AND (Date BETWEEN '{jsonParam.columnValue[0]}' AND '{jsonParam.columnValue[1]}')";

                    continue;
                }
                if (name == "CreditPoints")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                    switch (jsonParam.operationKey)
                    {
                        case "Include":
                            sql += $" WHERE {name} LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "NotInclude":
                            sql += $" WHERE {name} NOT LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "IsNull":
                            sql += $" WHERE {name} IS NULL";
                            break;
                        case "NotNull":
                            sql += $" WHERE {name} IS NOT NULL";
                            break;
                        case "Equal":
                            sql += $" WHERE {name} ='{jsonParam.columnValue}'";
                            break;
                        case "NotEqual":
                            sql += $" WHERE {name} !='{jsonParam.columnValue}'";
                            break;
                        case "GreaterOrEqual"://大于等于
                            sql += $" WHERE {name} >='{jsonParam.columnValue}'";
                            break;
                        case "Greater"://大于
                            sql += $" WHERE {name} >'{jsonParam.columnValue}'";
                            break;
                        case "LessOrEqual"://小于等于
                            sql += $" WHERE {name} <='{jsonParam.columnValue}'";
                            break;
                        case "Less"://小于
                            sql += $" WHERE {name} <'{jsonParam.columnValue}'";
                            break;
                        default:
                            break;
                    }

                    continue;
                }

                if (!string.IsNullOrWhiteSpace(value))
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                    switch (jsonParam.operationKey)
                    {
                        case "Include":
                            conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "NotInclude":
                            conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "IsNull":
                            conditions += $" AND {name} IS NULL";
                            break;
                        case "NotNull":
                            conditions += $" AND {name} IS NOT NULL";
                            break;
                        case "Equal":
                            conditions += $" AND {name} ='{jsonParam.columnValue}'";
                            break;
                        case "NotEqual":
                            conditions += $" AND {name} !='{jsonParam.columnValue}'";
                            break;
                        default:
                            break;
                    }
                }
            }

        sql = string.Format(sql, conditions);
        if (filter.pageSize == 0)
            filter.pageSize = 10000;
        var data = await Db.SqlQueryable<Ghre_CreditPointDetail>(sql)
            .OrderBy(filter.orderBy)
            .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount);

        return new ServicePageResult<Ghre_CreditPointDetail>(filter.pageNum, totalCount, filter.pageSize, data);
    }

}