
using System.Threading.Tasks;
using AutoMapper;

using IRaCIS.Application.Interfaces;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Image.QA;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.Service.Reading.Interface;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;


namespace IRaCIS.Core.API.Controllers
{

    [ApiController, ApiExplorerSettings(GroupName = "Reviewer")]
    [UnitOfWork]
    public class InspectionController : ControllerBase
    {
        private readonly IRepository _repository;
        private readonly IMapper _mapper;
        private readonly IUserInfo _userInfo;
        private readonly ITrialDocumentService _trialDocumentService;
        private readonly IQCListService _qCListService;
        private readonly IReadingImageTaskService _iReadingImageTaskService;
        private readonly IHttpContextAccessor _httpContext;
        private readonly ITrialConfigService _trialConfigService;
        private readonly INoneDicomStudyService _noneDicomStudyService;
        private readonly IClinicalAnswerService _clinicalAnswerService;
        private readonly ISubjectService _subjectService;
        private readonly IReadingClinicalDataService _readingClinicalDataService;
        private readonly ISubjectVisitService _subjectVisitService;
        private readonly IQCOperationService _qCOperationService;
        private readonly IClinicalDataService _clinicalDataService;
        private readonly IVisitPlanService _visitPlanService;
     
        private readonly IInspectionService _inspectionService;
        private readonly IReadingMedicalReviewService _readingMedicalReviewService;
        private readonly IReadingMedicineQuestionService _readingMedicineQuestionService;
        private readonly IRepository<DataInspection> _dataInspectionRepository;
        private delegate Task<IResponseOutput> executionFun(dynamic data);

        public InspectionController(IRepository repository,
            IRepository<DataInspection> _repositoryDataInspection,
            IMapper mapper, IUserInfo userInfo,
            ITrialDocumentService trialDocumentService,
            IRepository<DataInspection> dataInspectionRepository,
            IQCListService _qCListService,
              IReadingImageTaskService _iReadingImageTaskService,
            IHttpContextAccessor httpContext,
            IInspectionService sinspectionService,
              IReadingMedicalReviewService readingMedicalReviewService,
             IReadingMedicineQuestionService readingMedicineQuestionService,
            ITrialConfigService _trialConfigService,
            INoneDicomStudyService noneDicomStudyService,
            IClinicalAnswerService clinicalAnswerService,
            ISubjectService _subjectService,
            IReadingClinicalDataService _readingClinicalDataService,
            ISubjectVisitService subjectVisitService,
            IQCOperationService qCOperationService,
            IClinicalDataService clinicalDataService,
            IVisitPlanService visitPlanService
            )
        {
            this._repository = repository;
            this._mapper = mapper;
            this._userInfo = userInfo;
            this._inspectionService = sinspectionService;
            this._readingMedicalReviewService = readingMedicalReviewService;
            this._readingMedicineQuestionService = readingMedicineQuestionService;
            this._trialDocumentService = trialDocumentService;
            this._qCListService = _qCListService;
            this._iReadingImageTaskService = _iReadingImageTaskService;
            this._httpContext = httpContext;
            this._trialConfigService = _trialConfigService;
            this._noneDicomStudyService = noneDicomStudyService;
            this._clinicalAnswerService = clinicalAnswerService;
            this._subjectService = _subjectService;
            this._readingClinicalDataService = _readingClinicalDataService;
            this._subjectVisitService = subjectVisitService;
            this._qCOperationService = qCOperationService;
            this._clinicalDataService = clinicalDataService;
            this._visitPlanService = visitPlanService;
            this._dataInspectionRepository = dataInspectionRepository;
        }




        #region 获取稽查数据
        /// <summary>
        /// 获取稽查数据
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("Inspection/GetInspectionList")]
        public async Task<PageOutput<GetDataInspectionOutDto>> GetInspectionList(GetDataInspectionDto dto)
        {
            return await _inspectionService.GetInspectionList(dto);
        }
        #endregion

        /// <summary>
        /// 提交肿瘤学阅片任务
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/ReadingImageTask/SubmitOncologyReadingInfo")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> SetOncologyReadingInfo(DataInspectionDto<SubmitOncologyReadingInfoInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _iReadingImageTaskService.SubmitOncologyReadingInfo(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// 提交Diocm阅片
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/ReadingImageTask/SubmitDicomVisitTask")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> SubmitDicomVisitTask(DataInspectionDto<SubmitDicomVisitTaskInDto> opt)
        {

            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _iReadingImageTaskService.SubmitDicomVisitTask(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 提交全局阅片任务
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/ReadingImageTask/SubmitGlobalReadingInfo")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> SubmitGlobalReadingInfo(DataInspectionDto<SubmitGlobalReadingInfoInDto> opt)
        {

            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _iReadingImageTaskService.SubmitGlobalReadingInfo(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 项目阅片信息签名
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/TrialReadingInfoSign")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> TrialReadingInfoSign(DataInspectionDto<TrialReadingInfoSignInDto> opt)
        {
        
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _trialConfigService.TrialReadingInfoSign(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 医学审核完成
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ReadingMedicalReview/FinishMedicalReview")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> FinishMedicalReview(DataInspectionDto<FinishMedicalReviewInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _readingMedicalReviewService.FinishMedicalReview(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// 确认项目医学审核问题
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ReadingMedicineQuestion/ConfirmReadingMedicineQuestion")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> ConfirmReadingMedicineQuestion(DataInspectionDto<ConfirmReadingMedicineQuestionInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _readingMedicineQuestionService.ConfirmReadingMedicineQuestion(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 提交阅片问题
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ReadingImageTask/SubmitVisitTaskQuestions")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> SubmitVisitTaskQuestions(DataInspectionDto<SubmitVisitTaskQuestionsInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _iReadingImageTaskService.SubmitVisitTaskQuestions(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// CRC签名临床数据
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ClinicalAnswer/CRCSignClinicalData")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> CRCSignClinicalData(DataInspectionDto<CRCSignClinicalDataInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _clinicalAnswerService.CRCSignClinicalData(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// CRC确认临床数据
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ClinicalAnswer/CRCConfirmClinical")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> CRCConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _clinicalAnswerService.CRCConfirmClinical(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// CRC撤销临床数据
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ClinicalAnswer/CRCCancelConfirmClinical")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> CRCCancelConfirmClinical(DataInspectionDto<CRCCancelConfirmClinicalInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _clinicalAnswerService.CRCCancelConfirmClinical(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// PM确认临床数据
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ClinicalAnswer/PMConfirmClinical")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> PMConfirmClinical(DataInspectionDto<CRCConfirmClinicalInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _clinicalAnswerService.PMConfirmClinical(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


         /// <summary>
         /// 提交结构化录入并签名
         /// </summary>
         /// <param name="opt"></param>
         /// <returns></returns>
        [HttpPost, Route("Inspection/ClinicalAnswer/SubmitClinicalFormAndSign")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> SubmitClinicalFormAndSign(DataInspectionDto<SubmitClinicalFormInDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _clinicalAnswerService.SubmitClinicalForm(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// 提交阅片裁判问题
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ReadingImageTask/SubmitJudgeVisitTaskResult")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]

        [UnitOfWork]
        public async Task<IResponseOutput> SubmitJudgeVisitTaskResult(DataInspectionDto<SaveJudgeVisitTaskResult> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _iReadingImageTaskService.SubmitJudgeVisitTaskResult(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 配置 基础逻辑信息并确认
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialBasicInfoConfirm")]
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
        public async Task<IResponseOutput> ConfigTrialBasicInfoConfirm(DataInspectionDto<BasicTrialConfig> opt)
        {

            opt.Data.IsTrialBasicLogicConfirmed = true;
            var singid=  await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _trialConfigService.ConfigTrialBasicInfo(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }



        /// <summary>
        /// 配置流程并确认
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialProcessInfoConfirm")]
        [UnitOfWork]
        //[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
        public async Task<IResponseOutput> ConfigTrialProcessInfoConfirm(DataInspectionDto<TrialProcessConfig> opt)
        {
            opt.Data.IsTrialProcessConfirmed = true;

            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _trialConfigService.ConfigTrialProcessInfo(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


      


        /// <summary>
        /// 配置加急信息并确认
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialUrgentInfoConfirm")]
        [UnitOfWork]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
        public async Task<IResponseOutput> ConfigTrialUrgentInfoConfirm(DataInspectionDto<TrialUrgentConfig> opt)
        {
            opt.Data.IsTrialUrgentConfirmed = true;
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var  result=  await _trialConfigService.ConfigTrialUrgentInfo(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// 签名确认
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("Inspection/configTrialBasicInfo/TrialConfigSignatureConfirm")]
        [UnitOfWork]
         [TypeFilter(typeof(TrialResourceFilter),Arguments = new object[] { "AfterStopCannNotOpt" })]

        public async Task<IResponseOutput> TrialConfigSignatureConfirm(DataInspectionDto<SignConfirmDTO> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _trialConfigService.TrialConfigSignatureConfirm(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }



        /// <summary>
        /// CRC RequestToQC  批量提交
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _qCOperationService.CRCRequestToQC(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 设置QC 通过或者不通过   7:QC failed  8：QC passed  
        /// </summary>
        [HttpPost, Route("Inspection/QCOperation/QCPassedOrFailed")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> QCPassedOrFailed(DataInspectionDto<QCPassedOrFailedDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result= await _qCOperationService.QCPassedOrFailed(opt.Data.trialId, opt.Data.subjectVisitId, opt.Data.auditState);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// 一致性核查 回退  对话记录不清除  只允许PM回退
        /// </summary>
        [HttpPost, Route("Inspection/QCOperation/CheckBack")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> CheckBack(DataInspectionDto<IDDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result =  await _qCOperationService.CheckBack(opt.Data.Id);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 影像阅片临床数据签名
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/ReadClinicalData/ReadClinicalDataSign")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> ReadClinicalDataSign(DataInspectionDto<ReadingClinicalDataSignIndto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _readingClinicalDataService.ReadClinicalDataSign(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// CRC  设置已经重传完成
        /// </summary>
        [HttpPost, Route("Inspection/QCOperation/SetReuploadFinished")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> SetReuploadFinished(DataInspectionDto<CRCReuploadFinishedCommand> opt) 
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _qCOperationService.SetReuploadFinished(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }

        /// <summary>
        /// 更新项目状态
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/TrialConfig/updateTrialState")]
        //[TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> UpdateTrialState(DataInspectionDto<UpdateTrialStateDto> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _trialConfigService.UpdateTrialState(opt.Data.trialId, opt.Data.trialStatusStr, opt.Data.reason);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 用户 签名某个文档  
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("Inspection/TrialDocument/userConfirm")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "BeforeOngoingCantOpt", "SignSystemDocNoTrialId", "AfterStopCannNotOpt" })]
        [UnitOfWork]
        public async Task<IResponseOutput> UserConfirm(DataInspectionDto<UserConfirmCommand> opt)
        {
            var singid = await _inspectionService.RecordSing(opt.SignInfo);
            opt.Data.SignText = opt.SignInfo.SignText;
            var result = await _trialDocumentService.UserConfirm(opt.Data);
            await _inspectionService.CompletedSign(singid, result);
            return result;
        }


        /// <summary>
        /// 重阅同意
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("Inspection/VisitTask/ConfirmReReading")]
        [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })]
        [UnitOfWork]

        public async Task<IResponseOutput> ConfirmReReading(DataInspectionDto<ConfirmReReadingCommand> opt , [FromServices] IVisitTaskHelpeService _visitTaskCommonService,[FromServices] IVisitTaskService _visitTaskService)
        {
            var singId = await _inspectionService.RecordSing(opt.SignInfo);
            var result = await _visitTaskService.ConfirmReReading(opt.Data, _visitTaskCommonService);
            await _inspectionService.CompletedSign(singId, result);
            return result;
        }
  
    }
}
