using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Castle.Core.Internal;
using IRaCIS.Application.Contracts;
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.Inspection.DTO;
using IRaCIS.Core.Application.Service.Inspection.Interface;
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;
using Microsoft.EntityFrameworkCore;

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 ITrialConfigService _trialConfigService;
        private readonly INoneDicomStudyService _noneDicomStudyService;
        private readonly ISubjectService _subjectService;
        private readonly ISubjectVisitService _subjectVisitService;
        private readonly IQCOperationService _qCOperationService;
        private readonly IClinicalDataService _clinicalDataService;
        private readonly IVisitPlanService _visitPlanService;
        private readonly IInspectionService _inspectionService;

        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,
            IInspectionService sinspectionService,
            ITrialConfigService _trialConfigService,
            INoneDicomStudyService noneDicomStudyService,
            ISubjectService _subjectService,
             
            ISubjectVisitService subjectVisitService,
            IQCOperationService qCOperationService,
            IClinicalDataService clinicalDataService,
            IVisitPlanService visitPlanService
            )
        {
            this._repository = repository;
            this._mapper = mapper;
            this._userInfo = userInfo;
            this._inspectionService = sinspectionService;
            this._trialDocumentService = trialDocumentService;
            this._qCListService = _qCListService;
            this._trialConfigService = _trialConfigService;
            this._noneDicomStudyService = noneDicomStudyService;
            this._subjectService = _subjectService;
            this._subjectVisitService = subjectVisitService;
            this._qCOperationService = qCOperationService;
            this._clinicalDataService = clinicalDataService;
            this._visitPlanService = visitPlanService;
            this._dataInspectionRepository = dataInspectionRepository;
        }

     

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

        #region 影像质疑
        /// <summary>
        /// 手动领取 或者取消 QC任务
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/QCOperation/ObtainOrCancelQCTask")]
        [UnitOfWork]
        public async Task<IResponseOutput> ObtainOrCancelQCTask(DataInspectionDto<ObtainOrCancelQCTaskDto> opt)
        {
            var fun = await _qCOperationService.ObtainOrCancelQCTask(opt.OptCommand.trialId, opt.OptCommand.subjectVisitId, opt.OptCommand.obtaionOrCancel);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }

        #endregion
        #region 影像上传


        /// <summary>
        /// 疾病进展确认评估
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/QCOperation/UpdateSubjectAndSVInfo")]
        [UnitOfWork]
        public async Task<IResponseOutput> UpdateSubjectAndSVInfo(DataInspectionDto<UploadSubjectAndVisitCommand> opt)
        {
            var fun = _qCOperationService.UpdateSubjectAndSVInfo;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }


        /// <summary>
        /// 删除影像
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/QCOperation/deleteStudyList")]
        [UnitOfWork]
        public async Task<IResponseOutput> deleteStudyList(DataInspectionDto<DeleteStudyList> opt)
        {
            var fun = await _qCOperationService.DeleteStudyList(opt.OptCommand.ids, opt.OptCommand.subjectVisitId, opt.OptCommand.trialId);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }

            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun);
        }


        /// <summary>
        /// CRC RequestToQC  批量提交
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/QCOperation/CRCRequestToQC")]
        [UnitOfWork]
        public async Task<IResponseOutput> CRCRequestToQC(DataInspectionDto<CRCRequestToQCCommand> opt)
        {
            var fun = _qCOperationService.CRCRequestToQC;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }


        /// <summary>
        /// 非DICOM影像新增编辑
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/noneDicomStudy/AddOrUpdateNoneDicomStudy")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdateNoneDicomStudy(DataInspectionDto<NoneDicomStudyAddOrEdit> opt)
        {
            var fun = await _noneDicomStudyService.AddOrUpdateNoneDicomStudy(opt.OptCommand);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            if (opt.OptCommand.Id == null)
            {
                Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
                keyValuePairs.Add("CodeView", fun.Data.StudyCode);
                opt.AuditInfo.JsonDetail = _inspectionService.AddJsonItem(opt.AuditInfo.JsonDetail, keyValuePairs);
            }

            opt.AuditInfo.GeneralId = fun.Data.Id;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun);
        }


        /// <summary>
        /// 删除非dicom
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/noneDicom/DeleteNoneDicomStudy")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeleteNoneDicomStudy(DataInspectionDto<IDDto> opt)
        {
            var fun = _noneDicomStudyService.DeleteNoneDicomStudy;
            opt.AuditInfo.GeneralId = opt.OptCommand.Id;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }



        /// <summary>
        /// 删除非dicom文件
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/noneDicom/deleteNoneDicomStudyFile")]
        [UnitOfWork]
        public async Task<IResponseOutput> deleteNoneDicomStudyFile(DataInspectionDto<IDDto> opt)
        {
            var fun = _noneDicomStudyService.DeleteNoneDicomStudyFile;
            opt.AuditInfo.GeneralId = opt.OptCommand.Id;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }

        #endregion
        #region 临床数据采集 ClinicalDataService 
        /// <summary>
        /// 新增或修改既往放疗史
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/clinicalData/AddOrUpdatePreviousHistory")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdatePreviousHistory(DataInspectionDto<PreviousHistoryAddOrEdit> opt)
        {
            var fun = await _clinicalDataService.AddOrUpdatePreviousHistory(opt.OptCommand);
            opt.AuditInfo.GeneralId = fun.Data;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun);
        }


        /// <summary>
        /// 删除既往放疗史
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/clinicalData/DeletePreviousHistory")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeletePreviousHistory(DataInspectionDto<IDDto> opt)
        {
            var fun = _clinicalDataService.DeletePreviousHistory;
            opt.AuditInfo.GeneralId = opt.OptCommand.Id;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }




        /// <summary>
        /// 新增或修改既往手术史
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/clinicalData/AddOrUpdatePreviousSurgery")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdatePreviousSurgery(DataInspectionDto<PreviousSurgeryAddOrEdit> opt)
        {
            var fun = await _clinicalDataService.AddOrUpdatePreviousSurgery(opt.OptCommand);
            opt.AuditInfo.GeneralId = fun.Data;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun);
        }


        /// <summary>
        /// 删除既往手术史
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/clinicalData/DeletePreviousSurgery")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeletePreviousSurgery(DataInspectionDto<IDDto> opt)
        {
            var fun = _clinicalDataService.DeletePreviousSurgery;
            opt.AuditInfo.GeneralId = opt.OptCommand.Id;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }


        /// <summary>
        /// 新增或修改既往其他治疗史
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/clinicalData/AddOrUpdatePreviousOther")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdatePreviousOther(DataInspectionDto<PreviousOtherAddOrEdit> opt)
        {
            var fun = await _clinicalDataService.AddOrUpdatePreviousOther(opt.OptCommand);
            opt.AuditInfo.GeneralId = fun.Data;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo,null, fun);
        }


        /// <summary>
        /// 删除既往其他治疗史
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/clinicalData/DeletePreviousOther")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeletePreviousOther(DataInspectionDto<IDDto> opt)
        {

            var fun = _clinicalDataService.DeletePreviousOther;
            opt.AuditInfo.GeneralId = opt.OptCommand.Id;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }
        #endregion
        #region 访视计划
        /// <summary>
        /// 新增或添加访视计划
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/VisitPlan/AddOrUpdateVisitStage")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdateVisitStage(DataInspectionDto<VisitPlanCommand> opt)
        {
            var fun = await _visitPlanService.AddOrUpdateVisitStage(opt.OptCommand);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            opt.OptCommand.Id = Guid.Parse(fun.Data);
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }


        /// <summary>
        /// 删除访视计划对象
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/VisitPlan/DeleteVisitStage")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeleteVisitStage(DataInspectionDto<IDDto> opt)
        {
            var fun =  _visitPlanService.DeleteVisitStage;
          
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }

        /// <summary>
        /// 确认访视计划
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/VisitPlan/ConfirmTrialVisitPlan")]
        [UnitOfWork]
        public async Task<IResponseOutput> ConfirmTrialVisitPlan(DataInspectionDto<IDDto> opt)
        {
            var fun = _visitPlanService.ConfirmTrialVisitPlan;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }



        /// <summary>
        /// 下载访视计划
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/VisitPlan/DownloadInflunceStudyList")]
        [UnitOfWork]
        public async Task<IResponseOutput> DownloadInflunceStudyList(DataInspectionDto<IDDto> opt)
        {
            var fun = _visitPlanService.DownloadInflunceStudyList;
            return await _inspectionService.Enforcement(opt.OptCommand.Id, opt.AuditInfo, opt.SignInfo, fun);
        }
        #endregion
        #region 访视

        [HttpPost, Route("Inspection/subjectVisit/addOrUpdateSV")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdateSV(DataInspectionDto<SubjectVisitCommand> opt)
        {
            var fun = await _subjectVisitService.AddOrUpdateSV(opt.OptCommand);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            opt.AuditInfo.SubjectVisitId = Guid.Parse(fun.Data);
            opt.AuditInfo.SubjectVisitName = opt.OptCommand.VisitName;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }


        [HttpPost, Route("Inspection/subjectVisit/SetSubjectVisitUrgent")]
        [UnitOfWork]
        public async Task<IResponseOutput> SetSubjectVisitUrgent(DataInspectionDto<SetSubjectVisitUrgentCommand> opt)
        {

            var fun = await _subjectVisitService.SetSubjectVisitUrgent(opt.OptCommand.SubjectVisitId, opt.OptCommand.isUrgent);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }


        [HttpPost, Route("Inspection/subjectVisit/DeleteSV")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeleteSV(DataInspectionDto<DeleteSVCommand> opt)
        {

            var fun = await _subjectVisitService.DeleteSV(opt.OptCommand.SubjectVisitId);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }

        [HttpPost, Route("Inspection/subjectVisit/SetSVExecuted")]
        [UnitOfWork]
        public async Task<IResponseOutput> SetSVExecuted(DataInspectionDto<DeleteSVCommand> opt)
        {

            var fun = await _subjectVisitService.SetSVExecuted(opt.OptCommand.SubjectVisitId);
            if (!fun.IsSuccess)
            {
                return ResponseOutput.NotOk(fun.ErrorMessage);
            }
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }

        #endregion
        #region 配置项目信息
        /// <summary>
        /// 配置 基础逻辑信息
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/configTrialBasicInfo")]
        [UnitOfWork]
        public async Task<IResponseOutput> ConfigTrialBasicInfo(DataInspectionDto<BasicTrialConfig> opt)
        {
            var fun = _trialConfigService.ConfigTrialBasicInfo;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }

        /// <summary>
        /// 配置流程
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/configTrialProcessInfo")]
        [UnitOfWork]
        public async Task<IResponseOutput> ConfigTrialProcessInfo(DataInspectionDto<TrialProcessConfig> opt)
        {
            var fun = _trialConfigService.ConfigTrialProcessInfo;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }

        /// <summary>
        /// 配置加急信息
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns> 
        [HttpPost, Route("Inspection/configTrialBasicInfo/ConfigTrialUrgentInfo")]
        [UnitOfWork]
        public async Task<IResponseOutput> ConfigTrialUrgentInfo(DataInspectionDto<TrialUrgentConfig> opt)
        {
            var fun = _trialConfigService.ConfigTrialUrgentInfo;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }

        /// <summary>
        /// 签名确认
        /// </summary>
        /// <param name="signConfirmDTO">签名确认</param>
        /// <returns></returns>
        [HttpPost, Route("Inspection/configTrialBasicInfo/TrialConfigSignatureConfirm")]
        [UnitOfWork]
        public async Task<IResponseOutput> TrialConfigSignatureConfirm(DataInspectionDto<SignConfirmDTO> opt)
        {
            var fun = _trialConfigService.TrialConfigSignatureConfirm;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }
        #endregion
        #region 受试者
        /// <summary>
        /// 添加或更新受试者信息[New]
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        //[TypeFilter(typeof(TrialResourceFilter))]
        [HttpPost, Route("Inspection/Subject/AddOrUpdateSubject")]
        [UnitOfWork]
        public async Task<IResponseOutput> AddOrUpdateSubject(InsSubjectCommand opt)
        {


            opt.AuditInfo.SubjectCode = opt.OptCommand.Code;
            var fun = await _subjectService.AddOrUpdateSubject(opt.OptCommand);
            opt.AuditInfo.SubjectId = Guid.Parse(fun.Data);
            //var statusdata = new
            //{
            //    Status = "OnVisit",
            //    //OutEnrollmentTime = DateTime.Now.ToString("yyyy-MM-dd"),
            //    //VisitOverTime = DateTime.Now.ToString("yyyy-MM-dd"),
            //    Reason = string.Empty,
            //};

            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, null, fun);
        }

        /// <summary>
        /// 修改受试者状态
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        /// 
        [HttpPut, Route("Inspection/Subject/UpdateSubjectStatus")]
        [UnitOfWork]
        public async Task<IResponseOutput> UpdateSubjectStatus(InsUpdateSubjectStatus opt)
        {
            var fun = _subjectService.UpdateSubjectStatus;
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun);
        }


        /// <summary>
        /// 删除受试者
        /// </summary>
        /// <param name="opt"></param>
        /// <returns></returns>
        [HttpDelete, Route("Inspection/Subject/DeleteSubject")]
        [UnitOfWork]
        public async Task<IResponseOutput> DeleteSubject(InsDeleteSubjectDto opt)
        {
            var fun = _subjectService.DeleteSubject;
            opt.AuditInfo.SubjectCode = opt.OptCommand.Code;
            var data = await _subjectService.DeleteSubject(opt.OptCommand.SubjectId);
            return await _inspectionService.Enforcement(opt.OptCommand, opt.AuditInfo, opt.SignInfo, fun, data);
        }
        #endregion



    }




}