using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Request;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.QmsRepository.Repositories
{
    internal class QmsSensorDetailRepository : QMSRepositoryBase<siger_qms_sensor_detail>, IQmsSensorDetailRepository
    {
        private readonly ApiQmsDbContext _context;
        public QmsSensorDetailRepository(ApiQmsDbContext context) : base(context)
        {
            _context = context;
        }
        public IPagedCollectionResult<ResponseSensorReport> GetDetailData(RequestSensorMark condition, int projectId)
        {
            //转换时间
            var lastdtStart = (int)UnixTimeHelper.ConvertDataTimeLong(condition.lastdtBegin);
            var lastdtEnd = (int)UnixTimeHelper.ConvertDataTimeLong(condition.lastdtEnd);
            var nextdtStart = (int)UnixTimeHelper.ConvertDataTimeLong(condition.nextdtBegin);
            var nextdtEnd = (int)UnixTimeHelper.ConvertDataTimeLong(condition.nextdtEnd);
            //查询条件
            Expression<Func<ResponseSensorReport, bool>> funCode = f => true;
            if (!string.IsNullOrEmpty(condition.sensor_code))
            {
                funCode = f => f.sensor_code.Equals(condition.sensor_code);
            }
            Expression<Func<ResponseSensorReport, bool>> funType = f => true;
            if (condition.typeid != 0)
            {
                funType = f => f.typeid.Equals(condition.typeid);
            }
            Expression<Func<ResponseSensorReport, bool>> funSection = f => true;
            if (condition.sectionid != 0)
            {
                funSection = f => f.station.Equals(condition.sectionid);
            }
            if (condition.mid != 0)
            {
                funSection = f => f.equipment_value.Equals(condition.mid);
            }
            Expression<Func<ResponseSensorReport, bool>> funLast = f => true;
            if (lastdtStart != 0 && lastdtEnd != 0)
            {
                funLast = f => f.marktime_value >= lastdtStart && f.marktime_value <= lastdtEnd;
            }
            Expression<Func<ResponseSensorReport, bool>> funNext = f => true;
            if (nextdtEnd != 0 && nextdtStart != 0)
            {
                funNext = f => f.nextmarktime_value >= nextdtStart && f.nextmarktime_value <= nextdtEnd;
            }
            Expression<Func<ResponseSensorReport, bool>> funStatus = f => true;
            if (condition.status != 0)
            {
                funStatus = f => f.status == condition.status;
            }
            Expression<Func<ResponseSensorReport, bool>> funCheck = f => true;
            if (condition.checkuser != 0)
            {
                funCheck = f => f.checkuser_value == condition.checkuser;
            }
            Expression<Func<ResponseSensorReport, bool>> funAppove = f => true;
            if (condition.approvaluser != 0)
            {
                funAppove = f => f.approvaluser_value == condition.approvaluser;
            }
            Expression<Func<ResponseSensorReport, bool>> funModel = f => true;
            if (!string.IsNullOrEmpty(condition.model))
            {
                funModel = f => f.model.Equals(condition.model);
            }
            Expression<Func<ResponseSensorReport, bool>> funId = f => true;
            if (condition.id != 0)
            {
                funId = f => f.id.Equals(condition.id);
            }
            var predicates = funCode.And(funType).And(funLast).And(funNext).And(funSection).And(funStatus).And(funAppove).And(funCheck).And(funModel).And(funId);
            //query
            var query = from i in _context.siger_qms_sensor_parameter
                        join d in _context.siger_qms_sensor_detail on i.sensor_code equals d.sensor_code
                        join t in _context.siger_qms_sensor_type on i.typeid equals t.id
                        where i.projectid.Equals(projectId) && i.status != (int)RowState.Invalid
                        orderby i.mid
                        select new ResponseSensorReport
                        {
                            sensor_code = i.sensor_code,
                            name = i.name,
                            type = t.title,
                            model = i.model,
                            position = i.position,
                            marktime = UnixTimeHelper.ConvertStringDateTime(i.mark_time.ToStr()).ToStr(),
                            marktime_value = i.mark_time,
                            upload_time = d.upload_time.ToStr(),
                            nextmarktime_value = i.nexttime,
                            nextmarktime = UnixTimeHelper.ConvertStringDateTime(i.nexttime.ToStr()).ToStr(),
                            bind_manual = i.bind_manual,
                            validation_manual = i.validation_manual,
                            standard_procedure1 = i.standard_procedure1,
                            standard_procedure2 = i.standard_procedure2,
                            temperature = i.temperature,
                            humidity = i.humidity,
                            acceptable_precision1 = i.acceptable_precision1,
                            acceptable_precision2 = i.acceptable_precision2,
                            acceptable_precision3 = i.acceptable_precision3,
                            acceptable_precision4 = i.acceptable_precision4,
                            acceptable_precision5 = i.acceptable_precision5,
                            calibration_source = i.calibration_source,
                            sensor1_source = i.sensor1,
                            sensor2_source = i.sensor2,
                            sensor3_source = i.sensor3,
                            sensor4_source = i.sensor4,
                            fid = d.fid,
                            result = d.result,
                            historyfid = d.history_fid,
                            history_result = d.history_result,
                            appearance = d.appearance.ToStr(),
                            label = d.label.ToStr(),
                            remark = d.remark,
                            user_value = d.uid,
                            checkuser_value = d.checkuser,
                            checkuser2_value = d.checkuser2,
                            approvaluser_value = d.approvaluser,
                            status = d.status,
                            id = d.id,
                            station_value = i.station,
                            equipment_value = i.mid,
                        };
            var total = query.Count(predicates);
            var entities = query.Where(predicates).Skip((condition.page - 1) * condition.pagesize).Take(condition.pagesize).ToList();
            //加工数据
            var usermodel = _context.siger_project_user.Where(f => f.projectid.Equals(projectId) && f.status == 1).ToList();
            var sectionmodel = _context.siger_project_level_section.Where(f => f.projectid.Equals(projectId) && f.status == 1).ToList();
            var machinemodel = _context.siger_project_machine.Where(f => f.projectid.Equals(projectId) && f.status == 1).ToList();
            var fileModel = _context.siger_qms_sensor_file.Where(f => f.projectid.Equals(projectId) && f.status == 1).ToList();
            var sensorModel = _context.siger_qms_sensor_parameter.Where(f => f.projectid.Equals(projectId) && f.status != 0).ToList();
            foreach (var item in entities)
            {
                item.station = sectionmodel.FirstOrDefault(f => f.id.Equals(item.station_value))?.title ?? "";
                item.equipment = machinemodel.FirstOrDefault(f => f.id.Equals(item.equipment_value))?.title ?? "";
                item.user = usermodel.FirstOrDefault(f => f.mid.Equals(item.user_value))?.name ?? "";
                item.approvaluser = usermodel.FirstOrDefault(f => f.mid.Equals(item.approvaluser_value))?.name ?? "";
                item.checkuser = usermodel.FirstOrDefault(f => f.mid.Equals(item.checkuser_value))?.name ?? "";
                item.checkuser2 = usermodel.FirstOrDefault(f => f.mid.Equals(item.checkuser2_value))?.name ?? "";
                item.file_name = fileModel.FirstOrDefault(f => f.fid.Equals(item.fid) && f.type == (int)SensorFileType.File)?.file_name ?? "";
                item.history_file = fileModel.FirstOrDefault(f => f.fid.Equals(item.historyfid) && f.type == (int)SensorFileType.HistoryFile)?.file_name ?? "";
                //相关传感器信息获取
                var calibration_source = sensorModel.FirstOrDefault(f => f.sensor_code.Equals(item.calibration_source));
                if (calibration_source != null)
                {
                    item.calibration_source_name = calibration_source.name;
                    item.calibration_marktime = UnixTimeHelper.ConvertStringDateTime(calibration_source.mark_time.ToStr()).ToStr();
                    item.calibration_nextmarktime = UnixTimeHelper.ConvertStringDateTime(calibration_source.nexttime.ToStr()).ToStr();
                    item.calibration_range = calibration_source.range;
                    item.calibration_factory_precision = calibration_source.factory_precision;
                    item.calibration_file_name = GetMarkFile(calibration_source.sensor_code, projectId)?.file_name ?? "";
                }
                var sensor1 = sensorModel.FirstOrDefault(f => f.sensor_code.Equals(item.sensor1_source));
                if (sensor1 != null)
                {
                    item.sensor1_source_name = sensor1.name;
                    item.sensor1_marktime = UnixTimeHelper.ConvertStringDateTime(sensor1.mark_time.ToStr()).ToStr();
                    item.sensor1_nextmarktime = UnixTimeHelper.ConvertStringDateTime(sensor1.nexttime.ToStr()).ToStr();
                    item.sensor1_range = sensor1.range;
                    item.sensor1_factory_precision = sensor1.factory_precision;
                    item.sensor1_file_name = GetMarkFile(sensor1.sensor_code, projectId)?.file_name ?? "";
                }
                var sensor2 = sensorModel.FirstOrDefault(f => f.sensor_code.Equals(item.sensor2_source));
                if (sensor2 != null)
                {
                    item.sensor2_source_name = sensor2.name;
                    item.sensor2_marktime = UnixTimeHelper.ConvertStringDateTime(sensor2.mark_time.ToStr()).ToStr();
                    item.sensor2_nextmarktime = UnixTimeHelper.ConvertStringDateTime(sensor2.nexttime.ToStr()).ToStr();
                    item.sensor2_range = sensor2.range;
                    item.sensor2_factory_precision = sensor2.factory_precision;
                    item.sensor2_file_name = GetMarkFile(sensor2.sensor_code, projectId)?.file_name ?? "";
                }
                var sensor3 = sensorModel.FirstOrDefault(f => f.sensor_code.Equals(item.sensor3_source));
                if (sensor3 != null)
                {
                    item.sensor3_source_name = sensor3.name;
                    item.sensor3_marktime = UnixTimeHelper.ConvertStringDateTime(sensor3.mark_time.ToStr()).ToStr();
                    item.sensor3_nextmarktime = UnixTimeHelper.ConvertStringDateTime(sensor3.nexttime.ToStr()).ToStr();
                    item.sensor3_range = sensor3.range;
                    item.sensor3_factory_precision = sensor3.factory_precision;
                    item.sensor3_file_name = GetMarkFile(sensor3.sensor_code, projectId)?.file_name ?? "";
                }
                var sensor4 = sensorModel.FirstOrDefault(f => f.sensor_code.Equals(item.sensor4_source));
                if (sensor4 != null)
                {
                    item.sensor4_source_name = sensor4.name;
                    item.sensor4_marktime = UnixTimeHelper.ConvertStringDateTime(sensor4.mark_time.ToStr()).ToStr();
                    item.sensor4_nextmarktime = UnixTimeHelper.ConvertStringDateTime(sensor4.nexttime.ToStr()).ToStr();
                    item.sensor4_range = sensor4.range;
                    item.sensor4_factory_precision = sensor4.factory_precision;
                    item.sensor4_file_name = GetMarkFile(sensor4.sensor_code, projectId)?.file_name ?? "";
                }
                //填写结果
                switch (item.result)
                {
                    case "通过":
                        item.bind_pass = "✔";
                        break;
                    case "通过(警告)":
                        item.bind_warn = "✔";
                        break;
                    case "不通过":
                        item.bind_notpass = "✔";
                        break;
                    default:
                        break;
                }
                switch (item.history_result)
                {
                    case "报废":
                        item.history_scrap = "✔";
                        break;
                    case "维修":
                        item.history_reapir = "✔";
                        break;
                    case "让步接受":
                        item.history_accept = "✔";
                        break;
                    case "改变用途":
                        item.history_change = "✔";
                        break;
                    default:
                        break;
                }
                //上一次标定记录
                var lastDetails = _context.siger_qms_sensor_detail.Where(f => f.status != (int)RowState.Invalid && f.projectid.Equals(projectId)
                && f.sensor_code.Equals(item.sensor_code) && UnixTimeHelper.ConvertDataTimeLong(f.upload_time) < UnixTimeHelper.ConvertDataTimeLong(item.upload_time))
                .OrderByDescending(o => o.upload_time).FirstOrDefault();
                if (lastDetails != null)
                {
                    if (lastDetails.result!=null&& lastDetails.result== "不通过")
                    {
                        item.lastvalidation_failed = "YES";
                        var fileData = _context.siger_qms_sensor_file.FirstOrDefault(f => f.fid.Equals(item.fid) && f.status == (int)RowState.Valid);
                        item.lastvalidation_report = fileData.file_name ?? "";
                    }
                    else
                    {
                        item.lastvalidation_failed = "NO";
                    }
                }
            }
            return new PagedCollectionResult<ResponseSensorReport>(entities, total);
        }

        private siger_qms_sensor_file GetMarkFile(string sensorcode, int projectid)
        {
            var detail = _context.siger_qms_sensor_detail.Where(
                            d => d.projectid.Equals(projectid)
                         && d.status == (int)SensorResult.Pass
                         && d.sensor_code.Equals(sensorcode))
                         .OrderByDescending(o => o.approve_time)
                         .FirstOrDefault();
            if (detail == null)
            {
                return null;
            }
            var query = _context.siger_qms_sensor_file.FirstOrDefault(f => f.fid.Equals(detail.fid) && f.type == (int)SensorFileType.File && f.status != (int)RowState.Invalid);
            return query;
        }
    }
}
