#pragma once

#include "office/ExcelWrapper.h"

#include "ccl/rslang/SDataCompact.h"

namespace xtr::io {

class RSExcelIOManager {
  MSO::Excel::ExcelWrapper xlWrapper{};
  MSO::Excel::EXLWorkbook workingWb{ nullptr };
  MSO::Excel::EXLWorksheet workingWs{ nullptr };
  const ccl::semantic::RSModel& model;

  enum class OutputColumn : long {
    id = 1,
    constituenta = 2,
    expression = 3,
    type = 4,
    term = 5,
    interpretation = 6,
    convention = 7
  };

public:
  ~RSExcelIOManager();
  RSExcelIOManager(const RSExcelIOManager&) = delete;
  RSExcelIOManager& operator=(const RSExcelIOManager&) = delete;

  explicit RSExcelIOManager(const ccl::semantic::RSModel& model)
    : model{ model } {}

public:
  BOOL ExportModel();
  BOOL ExportDataFor(EntityUID target);

  [[nodiscard]] std::optional<ccl::object::SDCompact> ImportStructured(const ccl::rslang::Typification& structure);
  [[nodiscard]] std::optional<ccl::semantic::TextInterpretation> ImportText();

private:
  using RawStringData = std::vector<std::vector<CString>>;

  void ExportCstProperties(EntityUID target, MSO::Excel::EXLWorksheet rsFormSheet, MSO::SizeT nRow);
  BOOL ExportCstDataInternal(EntityUID target);
  std::optional<ccl::object::SDCompact> ImportStructuredInternal(const ccl::rslang::Typification& structure);
  std::optional<ccl::semantic::TextInterpretation> ImportTextInternal();

  BOOL PrepareNewWorkbook();
  MSO::Excel::EXLWorksheet InitModelWorksheet(CString label);
  MSO::Excel::EXLWorksheet CreateOutputSheet(CString label);
  void ExportNamedData(EntityUID target);
  BOOL ExportStructuredData(EntityUID target);
  void InitCstDataHeader(const std::vector<std::string>& header);

  BOOL PrepareInputWorksheet();
  BOOL DetermineWorksheet();

  BOOL CheckHeaders(const std::vector<std::string>& header);
  RawStringData ExtractRawData(MSO::SizeT columnCount);
  static std::optional<ccl::semantic::TextInterpretation> DataToTextInterpretation(const RawStringData& data);
  static std::optional<ccl::object::SDCompact::Data> DataToRSI(const RawStringData& data);
};

} // namespace xtr::io