using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests.ParserOptions;
using AsbCloudInfrastructure.Services.ExcelServices;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;

namespace AsbCloudInfrastructure.Services.WellOperations;

public class WellOperationParser<TTemplateParameters> : ExcelWellRelatedParser<WellOperationDto, WellOperationParserRequest, TTemplateParameters>
   where TTemplateParameters : class, ITemplateParameters, new()
{
   private readonly IEnumerable<WellSectionTypeDto> sectionTypes;
   private readonly IEnumerable<WellOperationCategoryDto> categories;

   public WellOperationParser(IWellOperationRepository wellOperationRepository,
      IWellOperationCategoryRepository categoryRepository)
   {
      categories = categoryRepository.Get(false);
      sectionTypes = wellOperationRepository.GetSectionTypes();
   }

   public override ParserResultDto<WellOperationDto> Parse(Stream file, WellOperationParserRequest options)
   {
      var result = base.Parse(file, options);

      foreach (var dto in result.Item)
      {
         dto.Item.IdWell = options.IdWell;
         dto.Item.IdType = options.IdType;
         dto.Item.DateStart = new DateTimeOffset(dto.Item.DateStart.DateTime, options.WellTimezone.Offset);
      }

      return result;
   }

   protected override WellOperationDto BuildDto(IDictionary<string, object?> row, int rowNumber)
   {
      var dto = base.BuildDto(row, rowNumber);

      var sectionType = sectionTypes.FirstOrDefault(s =>
         string.Equals(s.Caption.Trim(), dto.WellSectionTypeCaption?.Trim(), StringComparison.CurrentCultureIgnoreCase));

      if (sectionType is null)
      {
         var message = string.Format(XLExtentions.ProblemDetailsTemplate,
            TemplateParameters.SheetName,
            rowNumber,
            TemplateParameters.Cells[nameof(WellOperationDto.WellSectionTypeCaption)].ColumnNumber,
            "Указана некорректная секция");
         throw new FileFormatException(message);
      }

      var category = categories.FirstOrDefault(c =>
         string.Equals(c.Name.Trim(), dto.OperationCategoryName?.Trim(), StringComparison.CurrentCultureIgnoreCase));

      if (category is null)
      {
         var message = string.Format(XLExtentions.ProblemDetailsTemplate,
            TemplateParameters.SheetName,
            rowNumber,
            TemplateParameters.Cells[nameof(WellOperationDto.OperationCategoryName)].ColumnNumber,
            "Указана некорректная операция");
         throw new FileFormatException(message);
      }

      dto.IdWellSectionType = sectionType.Id;
      dto.IdCategory = category.Id;
      dto.IdParentCategory = category.IdParent;
      
      return dto;
   }
}