using ReportGenerator.Generator.Abstract;
using ReportGenerator.Generator.Interface;
using System.Text;

namespace ReportGenerator.Generator.Generator;

internal class CollapsibleHtmlTableGenerator : HtmlTableGenerator
{
  public string DetailsClass { get; init; }
  public string Summary { get; init; } = "Show table";

  /// <inheritdoc />
  public CollapsibleHtmlTableGenerator(int columns)
    : base(columns) { }

  /// <inheritdoc />
  public CollapsibleHtmlTableGenerator(int columns, Stream stream)
    : base(columns, stream) { }

  /// <inheritdoc />
  public CollapsibleHtmlTableGenerator(int columns, Stream stream, Encoding encoding)
    : base(columns, stream, encoding) { }

  #region Overrides of HtmlTableGenerator

  /// <inheritdoc />
  protected override void OnOpen()
  {
    Writer.Write($"<details class=\"{DetailsClass}\" open>");
    Writer.Write(HtmlTools.Wrap("summary", Summary));
    base.OnOpen();
  }

  /// <inheritdoc />
  protected override void OnClose()
  {
    base.OnClose();
    Writer.Write($"</details>");
  }

  #endregion
}

internal class HtmlTableGenerator : TableGeneratorBase
{
  public string Class { get; init; }

  private static readonly (string start, string end) rowFormat = ("<tr>", "</tr>");
  private static readonly (string start, string end) headerFormat = ("<th>", "</th>");
  private static readonly (string start, string end) columnFormat = ("<td>", "</td>");

  /// <inheritdoc />
  public HtmlTableGenerator(int columns) : base(columns) { }

  /// <inheritdoc />
  public HtmlTableGenerator(int columns, Stream stream) : base(columns, stream) { }

  /// <inheritdoc />
  public HtmlTableGenerator(int columns, Stream stream, Encoding encoding) : base(columns, stream,
    encoding)
  { }

  #region State

  /// <inheritdoc />
  protected override void OnOpen()
  {
    base.OnOpen();
    Writer.Write($"<table class={Class}>");
  }

  /// <inheritdoc />
  protected override void OnClose()
  {
    base.OnClose();
    Writer.Write("</table>");
  }

  #endregion

  #region Writing

  /// <inheritdoc />
  public override ITableGenerator AppendHeader(IEnumerable<string> row) =>
    AppendRow(row, rowFormat, headerFormat);

  /// <inheritdoc />
  public override ITableGenerator AppendRow(IEnumerable<string> row) =>
    AppendRow(row, rowFormat, columnFormat);

  private ITableGenerator AppendRow(
    IEnumerable<string> row,
    (string, string) rowFormat,
    (string, string) columnFormat
  )
  {
    var (rowStart, rowEnd) = rowFormat;
    var (colStart, colEnd) = columnFormat;

    this
      .Write(rowStart)
      .Write(colStart)
      .Write(string.Join(colEnd + colStart, row))
      .Write(colEnd)
      .Write(rowEnd);

    return this;
  }

  #endregion
}
