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