using AgileObjects.AgileMapper.Extensions.Internal;

namespace Tiobon.Core.Services;

/// <summary>
/// 录用审批单 (服务)
/// </summary>
public class Ghrh_OfferApplyOrderServices : BaseServices<Ghrh_OfferApplyOrder, Ghrh_OfferApplyOrderDto, InsertGhrh_OfferApplyOrderInput, EditGhrh_OfferApplyOrderInput>, IGhrh_OfferApplyOrderServices
{
    private readonly IBaseRepository<Ghrh_OfferApplyOrder> _dal;
    private readonly IGhrh_OfferApplyOrderSalaryServices _ghrh_OfferApplyOrderSalaryServices;
    public Ghrh_OfferApplyOrderServices(ICaching caching, IBaseRepository<Ghrh_OfferApplyOrder> dal, IGhrh_OfferApplyOrderSalaryServices ghrh_OfferApplyOrderSalaryServices)
    {
        this._dal = dal;
        base.BaseDal = dal;
        base._caching = caching;
        _ghrh_OfferApplyOrderSalaryServices = ghrh_OfferApplyOrderSalaryServices;
    }
    private async Task SetLabel(Ghrh_OfferApplyOrderDto x)
    {
        if (x != null)
        {
            x.InDate1 = DateTimeHelper.ConvertToDayString(x.InDate);
            x.ChannelLabel = await GetParaLabel("ResumeChannel", x.Channel);
            x.StaffTypeLabel = await GetParaLabel("StaffType2", x.StaffType);
            if (x.WorkState.IsNotEmptyOrNull())
            {
                if (x.WorkState == 0) x.WorkStateLabel = "审批中";
                if (x.WorkState == 1) x.WorkStateLabel = "审批通过";
            }
        }
    }

    public override async Task<ServicePageResult<Ghrh_OfferApplyOrderDto>> QueryFilterPage(QueryBody filter, string condition, bool? IsEnable = true)
    {
        var result = await base.QueryFilterPage(filter, $"dbo.[FUserDeptPriv] ({App.User.ID}, DeptId, getdate())=1", IsEnable);
        var entitys = result.result.DT_TableDataT1;

        var deptIds = entitys.Where(x => x.DeptId != null).Select(x => x.DeptId).ToList();
        var gradeIds = entitys.Where(x => x.GradeId != null).Select(x => x.GradeId).ToList();
        var titleIds = entitys.Where(x => x.TitleId != null).Select(x => x.TitleId).ToList();
        var jobIds = entitys.Where(x => x.JobId != null).Select(x => x.JobId).ToList();
        var reportIds = entitys.Where(x => x.ReportId != null).Select(x => x.ReportId).ToList();
        reportIds.AddRange(entitys.Where(x => x.ApplicantId != null).Select(x => x.ApplicantId).ToList());
        var zoneIds = entitys.Where(x => x.ZoneId != null).Select(x => x.ZoneId).ToList();

        if (zoneIds.Any())
        {
            var zones = await Db.Queryable<Ghra_Zone>().Where(x => zoneIds.Contains(x.ZoneID)).ToListAsync();

            entitys.ForEach(rule =>
            {
                if (rule.ZoneId != null)
                    rule.ZoneName = zones.FirstOrDefault(o => rule.ZoneId == o.ZoneID)?.ZoneName;
            });
        }
        if (reportIds.Any())
        {
            var staffs = await Db.Queryable<Ghra_Staff>().Where(x => reportIds.Contains(x.StaffID)).ToListAsync();

            entitys.ForEach(rule =>
            {
                rule.ReportName = staffs.FirstOrDefault(o => rule.ReportId == o.StaffID)?.StaffName;
                rule.ApplicantName = staffs.FirstOrDefault(o => rule.ApplicantId == o.StaffID)?.StaffName;
            });
        }

        if (deptIds.Any())
        {
            var depts = await Db.Queryable<Ghro_Dept>().Where(x => deptIds.Contains(x.DeptID)).ToListAsync();

            entitys.ForEach(rule =>
            {
                rule.DeptName = depts.FirstOrDefault(o => rule.DeptId == o.DeptID)?.DeptName;
            });
        }
        if (titleIds.Any())
        {
            var titles = await Db.Queryable<Ghra_Title>().Where(x => titleIds.Contains(x.TitleID)).ToListAsync();

            entitys.ForEach(rule =>
            {
                rule.TitleName = titles.FirstOrDefault(o => rule.TitleId == o.TitleID)?.TitleName;
            });
        }

        if (gradeIds.Any())
        {
            var grades = await Db.Queryable<Ghra_Grade>().Where(x => gradeIds.Contains(x.GradeID)).ToListAsync();

            entitys.ForEach(rule =>
            {
                rule.GradeName = grades.FirstOrDefault(o => rule.GradeId == o.GradeID)?.GradeName;
            });
        }

        if (jobIds.Any())
        {
            var jobs = await Db.Queryable<Ghra_Job>().Where(x => jobIds.Contains(x.JobID)).ToListAsync();

            entitys.ForEach(rule =>
            {
                rule.JobName = jobs.FirstOrDefault(o => rule.JobId == o.JobID)?.JobName;
            });
        }

        for (int i = 0; i < entitys.Count; i++)
        {
            await SetLabel(entitys[i]);

        }

        result.result.DT_TableDataT1 = entitys;
        return result;
    }

    public override async Task<long> Add(InsertGhrh_OfferApplyOrderInput entity)
    {

        entity.OrderNo = await GenerateContinuousSequence("Ghrh_OfferApplyOrder", "OrderNo", "LYSQ");
        entity.ApplicantId = GetStaffId();
        entity.ApplyTime = DateTime.Now;
        var id = await base.Add(entity);

        #region  写入数据,并判断是否有错误 
        var sql = $"SELECT ISNULL(MAX(id)+1,1) FROM Ghrh_OfferApplyOrder WHERE Id !='{id}'";
        var id1 = await Db.Ado.GetLongAsync(sql);
        sql = $"UPDATE Ghrh_OfferApplyOrder SET Id={id1} WHERE  Id ='{id}'";
        await Db.Ado.ExecuteCommandAsync(sql);
        id = id1;
        #endregion

        if (entity.Items.IsNotEmptyOrNull())
        {
            entity.Items.ForEach(x =>
            {
                x.OrderId = id;
            });
            await _ghrh_OfferApplyOrderSalaryServices.Add(entity.Items);
        }


        #region 生成流程数据
        sql = $"Select FlowID from Ghrw_Flow where FlowNo='F_ESS_RecruitOfferApply' AND IsEnable=1";
        int @FlowID = await Db.Ado.GetIntAsync(sql);
        sql = @$"DECLARE @return_value int;

                DECLARE @ErrorMsg nvarchar(2000);

                SET @ErrorMsg = NULL;

                EXEC  @return_value = dbo.[PT_GHR30_FlowApply] 
                    @ID = {id},
                    @FlowID = {@FlowID},
                    @UserID = {App.User.ID},
                    @LangID = 1,
                    @ErrorMsg = @ErrorMsg out;

                SELECT @ErrorMsg as N'@ErrorMsg', @return_value as N'@Return Value';";

        var message = await Db.Ado.GetStringAsync(sql);

        if (message.IsNotEmptyOrNull())
            throw new Exception(message);

        var order = await Db.Queryable<Ghrh_InterviewOrder>().FirstAsync(x => x.ResumeId == entity.ResumeId);

        var dict = new Dictionary<string, object>
        {
            { "Id", SnowFlakeSingle.Instance.NextId() },
            { "CreateBy", App.User.ID },
            { "CreateTime", DateTime.Now },
            { "InterviewOrderId", order.Id },
            { "ResumeId", entity.ResumeId },
            { "Source", "ApplyOffer" },
            { "UserId", App.User.ID },
            { "UserName", App.User.Name },
            { "RemarkSz", "发起录用审批！" },
            { "ReverseI2", id }
        };
        await Db.Insertable(dict).AS("Ghrh_InterviewLog").ExecuteCommandAsync();
        #endregion

        return id;
    }


    public async Task<ServiceResult<long>> TempAdd(long resumeId, InsertGhrh_OfferApplyOrderInput entity)
    {
        var order = await base.QuerySingle(x => x.ResumeId == resumeId);
        if (order is null)
        {
            var resume = await Db.Queryable<Ghrh_Resume>().Where(x => x.Id == resumeId).FirstAsync();
            entity.OrderNo = await GenerateContinuousSequence("Ghrh_OfferApplyOrder", "OrderNo", "L");
            entity.ApplicantId = GetStaffId();
            entity.ApplyTime = DateTime.Now;
            entity.WorkState = 1;
            entity.ResumeId = resumeId;
            entity.StaffName = resume.StaffName;
            entity.ResumeId = resumeId;
            var id = await base.Add(entity);

            #region  写入数据,并判断是否有错误 
            var sql = $"SELECT ISNULL(MAX(id)+1,1) FROM Ghrh_OfferApplyOrder WHERE Id !='{id}'";
            var id1 = await Db.Ado.GetLongAsync(sql);
            sql = $"UPDATE Ghrh_OfferApplyOrder SET Id={id1} WHERE  Id ='{id}'";
            await Db.Ado.ExecuteCommandAsync(sql);
            id = id1;
            #endregion

            if (entity.Items.IsNotEmptyOrNull())
            {
                entity.Items.ForEach(x =>
                {
                    x.OrderId = id;
                });
                await _ghrh_OfferApplyOrderSalaryServices.Add(entity.Items);
            }

            return ServiceResult<long>.OprateSuccess("保存成功", id);
        }
        else
        {
            var edit = Mapper.Map(entity).ToANew<EditGhrh_OfferApplyOrderInput>();
            await base.Update(order.Id, edit, null, ["OrderNo", "ApplicantId", "ApplyTime", "WorkState", "ResumeId"]);
            return ServiceResult<long>.OprateSuccess("修改成功！", order.Id);

        }
    }

    public override async Task<bool> Update(long Id, EditGhrh_OfferApplyOrderInput editModel)
    {

        return await base.Update(Id, editModel);
    }

    #region 查询招聘表单信息接口

    public static string NumberToChinese(int num)
    {
        string[] chineseDigits = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        string result = "";

        foreach (char digit in num.ToString())
        {
            // 将每个数字字符转换为对应的中文字符
            int index = int.Parse(digit.ToString());
            result += chineseDigits[index];
        }

        return result;
    }
    public async Task<ServiceResult<dynamic>> QueryResume(long resumeId)
    {
        dynamic obj = new ExpandoObject();

        var resume = await Db.Queryable<Ghrh_Resume>().Where(x => x.Id == resumeId).FirstAsync();

        if (resume == null)
            return ServiceResult<dynamic>.OprateFailed("无效的简历ID", obj);
        obj.StaffName = resume.StaffName;
        obj.IdCardNo = resume.IdCardNo;
        obj.ResumeId = resume.Id;
        obj.Channel = resume.Channel;
        var order = await Db.Queryable<Ghrh_InterviewOrder>().Where(x => x.ResumeId == resumeId).FirstAsync();
        if (order != null)
        {
            var columns = new JArray();

            obj.TitleId = order.HireTitleId;
            obj.DeptId = order.HireDeptId;
            obj.IdCardNo = resume.IdCardNo;
            var records = await Db.Queryable<Ghrh_InterviewRecord>().Where(x => x.OrderId == order.Id).OrderBy(x => x.Round).ToListAsync();
            var recordIds = records.Select(x => x.Id).ToList();
            var interviewAssessDetails = await Db.Queryable<Ghrh_InterviewAssessDetail>().Where(x => x.InterviewRecordId != null && recordIds.Contains(x.InterviewRecordId.Value)).ToListAsync();


            for (int i = 0; i < records.Count; i++)
            {
                var record = records[i];

                var staff = await Db.Queryable<Ghra_Staff>().Where(x => x.StaffID == record.StaffId).FirstAsync();
                var evaluate = interviewAssessDetails.Where(x => x.InterviewRecordId == record.Id && x.AssessConfigId == "EvaluateContent").FirstOrDefault();
                var pass = interviewAssessDetails.Where(x => x.InterviewRecordId == record.Id && x.AssessConfigId == "IsPass").FirstOrDefault();

                var item = new JObject
                {
                    new JProperty("Round", NumberToChinese(record.Round.Value)+"面\n"+ record.InterviewTime),
                    new JProperty("Interviewer", staff?.StaffName),
                };
                if (evaluate != null)
                    item.Add(new JProperty("EvaluateContent", evaluate.AssessContent));
                if (pass != null)
                {
                    if (pass.AssessContent == "1")
                        item.Add(new JProperty("PassLabel", "通过"));
                    else
                        item.Add(new JProperty("PassLabel", "不通过"));
                }

                columns.Add(item);

            }

            obj.InterviewRecord = columns;
        }

        var applyOrder = await base.QuerySingle(x => x.ResumeId == resumeId);
        if (applyOrder != null)
        {

            obj.CompanyId = applyOrder.CompanyId;
            obj.DeptId = applyOrder.DeptId;
            obj.TitleId = applyOrder.TitleId;
            obj.Channel = applyOrder.Channel;
            obj.StaffName = applyOrder.StaffName;
            obj.DeIdCardNoptId = applyOrder.IdCardNo;
            obj.InDate = applyOrder.InDate;
            obj.StaffType = applyOrder.StaffType;
            obj.GradeId = applyOrder.GradeId;
            obj.PeriodMasterId = applyOrder.PeriodMasterId;
            obj.JobId = applyOrder.JobId;
            obj.ProbationMonths = applyOrder.ProbationMonths;
            obj.ReportId = applyOrder.ReportId;
            obj.JobResponsibility = applyOrder.JobResponsibility;
            obj.WorkAddress = applyOrder.WorkAddress;
            obj.JobProbationSalaryId = applyOrder.ProbationSalary;
            obj.ProbationAfterSalary = applyOrder.ProbationAfterSalary;
            obj.JobPeriodMasterIdId = applyOrder.PeriodMasterId;
            obj.JobId = applyOrder.JobId;
            obj.ZoneId = applyOrder.ZoneId;
            obj.StaffType1 = applyOrder.StaffType1;

            obj.Items = await Db.Queryable<Ghrh_OfferApplyOrderSalary>().Where(x => x.OrderId == applyOrder.Id).ToListAsync();
        }

        obj.CurrencyId = await Db.Ado.GetIntAsync(@"SELECT CurrencyID
FROM Ghrc_Currency
WHERE IsDefault = 1 AND IsEnable = 1");

        return ServiceResult<dynamic>.OprateSuccess("查询成功", obj);

    }
    #endregion
}