using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;

namespace IRaCIS.Core.Application.Services
{
    [ApiExplorerSettings(GroupName = "Image")]
    [AllowAnonymous]
    public class SeriesService(IRepository<DicomSeries> _seriesRepository,
        IRepository<DicomInstance> _instanceRepository,
        IRepository<SCPSeries> _scpSeriesRepository,
        IRepository<SCPInstance> _scpInstanceRepository,
        IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService
    {


        /// <summary>
        /// 更新缩略图路径
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> UpdateImageResizePath(UpdateImageResizeDTO dto)
        {
            await _seriesRepository.UpdatePartialFromQueryAsync(t => t.Id == dto.SeriesId, u => new DicomSeries() { ImageResizePath = dto.ImageResizePath }, true);

            return ResponseOutput.Ok();
        }

        //医生读片那一块有耦合，关键序列   这里暂时留存
        /// <summary> 指定资源Id，获取Dicom检查所属序列信息列表 </summary>
        /// <param name="studyId"> Dicom检查的Id </param>
        /// <param name="isReading"></param>
        [HttpGet, Route("{studyId:guid}")]
        public async Task<IResponseOutput<List<DicomSeriesDTO>>> List(Guid studyId, bool? isReading, bool? isPacs)
        {
            if (isPacs == true)
            {
                var seriesList = await _scpSeriesRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
                   .OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
                 .ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();

                var instanceList = await _scpInstanceRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
                     .OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
                     .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
                    .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.FileSize, t.ImagePositionPatient, t.ImageOrientationPatient }).ToListAsync();//.GroupBy(u => u.SeriesId);


                foreach (var series in seriesList)
                {

                    var instances = instanceList.Where(x => x.SeriesId == series.Id);

                    // ⭐ DICOM 空间排序（带兜底）
                    var sorted = DicomSortHelper.SortSlices(
                        instances,
                        x => x.ImagePositionPatient,
                        x => x.ImageOrientationPatient,
                        x => x.InstanceNumber
                    );

                    series.InstanceInfoList = sorted.Select(k =>
                       new InstanceBasicInfo()
                       {
                           Id = k.Id,
                           NumberOfFrames = k.NumberOfFrames,
                           HtmlPath = string.Empty,
                           Path = k.Path,
                           InstanceNumber = k.InstanceNumber,
                           IsReading = true,
                           IsDeleted = false,
                           FileSize = k.FileSize,
                           

                       }).ToList();

                    series.InstanceCount = series.InstanceInfoList.Count;
                }

                return ResponseOutput.Ok(seriesList);

            }
            else
            {
                //质控的时候，要标记序列，和instance 删除  ，所以要返回全部，但是 质控通过后，pm 进去看的时候要看过滤后的

                var qcAuditState = await _seriesRepository.Where(s => s.StudyId == studyId).Select(t => t.DicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();

                //质控通过以后，预览过滤删除的   质控之前的不过滤
                var isQCFinished = qcAuditState == AuditStateEnum.QCPassed;

                //断点
                var seriesList = await _seriesRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
                    .WhereIf(isQCFinished, t => t.IsDeleted == false)
                    .WhereIf(isReading == true, t => t.IsReading == true)
                    .OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
                  .ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();

                var instanceList = await _instanceRepository.Where(s => s.StudyId == studyId).IgnoreQueryFilters()
                     .WhereIf(isQCFinished, t => t.IsDeleted == false)
                     .WhereIf(isReading == true, t => t.IsReading == true)
                     .OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
                     .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
                    .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.HtmlPath, t.IsReading, t.IsDeleted, t.FileSize ,t.IsMasked}).ToListAsync();//.GroupBy(u => u.SeriesId);


                foreach (var series in seriesList)
                {

                    series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
                       new InstanceBasicInfo()
                       {
                           Id = k.Id,
                           NumberOfFrames = k.NumberOfFrames,
                           HtmlPath = k.HtmlPath,
                           Path = k.Path,
                           InstanceNumber = k.InstanceNumber,
                           IsReading = k.IsReading,
                           IsDeleted = k.IsDeleted,
                           FileSize = k.FileSize,
                           IsMasked = k.IsMasked

                       }).ToList();

                    series.InstanceCount = series.InstanceInfoList.Count;
                }

                return ResponseOutput.Ok(seriesList);

            }






        }





        /// <summary> 指定资源Id，渲染Dicom序列的Jpeg预览图像 </summary>
        /// <param name="seriesId"> Dicom序列的Id </param>
        [HttpGet, Route("{seriesId:guid}")]
        [AllowAnonymous]
        public async Task<FileContentResult> Preview(Guid seriesId)
        {
            string path = string.Empty;

            path = (await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException();

            #region 切换磁盘存储之前
            //var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);

            #endregion

            #region 切换磁盘存储后

            var physicalPath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, path);

            //不存在，去其他路径找
            if (!File.Exists(physicalPath))
            {
                //找到所有磁盘
                var drives = DriveInfo.GetDrives()
                         .Where(d => d.DriveType == DriveType.Fixed && d.IsReady)
                         //剩余空间最多的
                         .OrderByDescending(d => d.AvailableFreeSpace)

                         //存储空间相同，则按照按照总空间从大到小排序
                         .ThenByDescending(d => d.TotalSize - d.TotalFreeSpace)
                         .Select(d => d.RootDirectory.FullName)
                         .ToList();


                foreach (var drive in drives)
                {
                    physicalPath = Path.Combine(drive, _hostEnvironment.EnvironmentName, path.Trim('/'));

                    if (File.Exists(physicalPath))
                    {
                        break;
                    }
                }
            }



            #endregion



            using (var sw = ImageHelper.RenderPreviewJpeg(physicalPath))
            {
                var bytes = new byte[sw.Length];
                sw.Read(bytes, 0, bytes.Length);
                sw.Close();
                return new FileContentResult(bytes, "image/jpeg");
            }
        }


    }
}