using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System.Linq.Dynamic.Core;

namespace IRaCIS.Core.Application.Services
{
    [ApiExplorerSettings(GroupName = "Image")]
    [AllowAnonymous]
    public class InstanceService(IRepository<DicomInstance> _instanceRepository,
        IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, IInstanceService
    {


        /// <summary> 指定资源Id，获取Dicom序列所属的实例信息列表 </summary>
        /// <param name="seriesId"> Dicom序列的Id </param>
        [HttpGet("{seriesId:guid}")]
        public async Task<IResponseOutput<List<DicomInstanceDTO>>> List(Guid seriesId)
        {
            var qcAuditState = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => t.DicomStudy.SubjectVisit.AuditState).FirstOrDefaultAsync();

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

            var list = await _instanceRepository.Where(s => s.SeriesId == seriesId).IgnoreQueryFilters()
                .WhereIf(isQCFinished, t => t.IsDeleted == false)
                .OrderBy(s => s.InstanceNumber).ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
                .ProjectTo<DicomInstanceDTO>(_mapper.ConfigurationProvider).ToListAsync();

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

            var seriesInfo = await _instanceRepository.Where(s => s.SeriesId == seriesId).Select(t => new
            {
                t.DicomSerie.ImageResizePath,
                t.DicomSerie.IsDeleted,
                t.DicomSerie.IsReading,
                SubjectCode = t.DicomSerie.SubjectVisit.Subject.Code,
                t.DicomSerie.SubjectVisit.VisitName
            }).FirstOrDefaultAsync();

            return ResponseOutput.Ok(sorted, seriesInfo);
        }


        /// <summary> 指定资源Id，获取Dicom序列所属的实例Id列表 </summary>
        /// <param name="seriesId"> Dicom序列的Id </param>
        /// <param name="tpCode"></param>
        /// <param name="key"></param>
        [HttpGet, Route("{seriesId:guid}/{tpCode?}/{key?}")]
        public IEnumerable<Guid> List(Guid seriesId, string tpCode, bool? key)
        {
            //if (key != null && key.HasValue && key.Value)
            //{
            //    return _keyInstanceRepository.Where(s => s.TpCode == tpCode).Select(t => t.InstanceId).Distinct();
            //}
            //else
            return _instanceRepository.Where(s => s.SeriesId == seriesId).OrderBy(s => s.InstanceNumber).Select(t => t.Id);
        }

        [AllowAnonymous]
        [HttpGet, Route("{instanceId:guid}")]
        public async Task<FileContentResult> Preview(Guid instanceId)
        {
            var path = string.Empty;

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

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

            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");
            }


        }

        [AllowAnonymous]
        [HttpGet, Route("{instanceId:guid}")]
        public async Task<FileContentResult> Content(Guid instanceId)
        {
            var filePath = string.Empty;
            var path = (await _instanceRepository.Where(s => s.Id == instanceId).Select(t => t.Path).FirstOrDefaultAsync()).IfNullThrowException();


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


            using (var sw = new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var bytes = new byte[sw.Length];
                sw.Read(bytes, 0, bytes.Length);
                sw.Close();
                return new FileContentResult(bytes, "application/octet-stream");
            }
        }


    }
}