using System.Collections.Generic;
namespace LaDOSE.Entity
{
///
/// One spreadsheet write: the tables to put in it, and which spreadsheet.
/// Not an entity — never mapped by EF. It arrives as SheetExportRequestDTO and is
/// mapped by AutoMapper, same pattern as , so property names
/// must stay identical to the DTO's.
///
/// The tables are built client-side by $lib/tournaments/cumulative.ts, which reuses the
/// very same buildRanking() that produces the CSV export. That is deliberate: the sheet
/// and the CSV cannot drift because one function produces both.
///
public class SheetExportRequest
{
///
/// Resolved by SheetsExportService from configuration — never supplied by the caller,
/// so a client cannot aim the export at someone else's spreadsheet.
///
public string SpreadsheetId { get; set; }
///
/// One tab per selected event, oldest first. Tab N holds events 1..N merged, so the
/// last tab is the full cumulative ranking for the scope.
///
public List Tabs { get; set; } = new List();
}
/// One tab: a players x games grid with a Total column.
public class SheetTable
{
/// Desired tab title, e.g. "Ranking #1301". Sanitised before use.
public string Name { get; set; }
///
/// Provenance and logging only. Tabs are addressed by title, never by this — see the
/// note on tab identity in SheetsExportService.
///
public int EventId { get; set; }
/// ["Players", <game names...>, "Total"].
public List Header { get; set; } = new List();
public List Rows { get; set; } = new List();
///
/// Written below the grid, one line per entry, blank row in between. Carries which
/// events went into this tab so a stale or incomplete tab identifies itself.
///
public List Footer { get; set; } = new List();
}
public class SheetRow
{
public string Player { get; set; }
/// Index-aligned with Header[1..^1] — one entry per game column.
public List Points { get; set; } = new List();
public int Total { get; set; }
}
public class SheetExportResult
{
public string SpreadsheetId { get; set; }
public string SpreadsheetUrl { get; set; }
/// Which ISheetsWriter did the work — "ServiceAccount", "Logging", ...
public string Writer { get; set; }
public List Tabs { get; set; } = new List();
/// Anything the user should know but that did not stop the write, e.g. renames.
public List Warnings { get; set; } = new List();
}
public class SheetTabResult
{
/// The title as asked for, before sanitisation.
public string RequestedName { get; set; }
/// The title actually written to.
public string Name { get; set; }
public int Rows { get; set; }
public int Columns { get; set; }
/// False when an existing tab of that name was rewritten in place.
public bool Created { get; set; }
}
/// What the UI needs to render the export panel. Never carries a secret.
public class SheetsConfig
{
public string Writer { get; set; }
/// The writer has its credentials and a target spreadsheet is configured.
public bool Configured { get; set; }
public string SpreadsheetId { get; set; }
public int MaxTabs { get; set; }
public int MaxRowsPerTab { get; set; }
}
///
/// Server-side limits and the target spreadsheet, read from the GoogleSheets configuration
/// section. Constructor-injected rather than IOptions, matching how the Challonge and Smash
/// providers take their keys.
///
public class SheetsSettings
{
///
/// The spreadsheet everything is written to. Reset each year — see .env.example.
///
public string SpreadsheetId { get; set; }
public int MaxTabs { get; set; } = 60;
public int MaxRowsPerTab { get; set; } = 5000;
/// Google caps a tab at 100 chars; this caps the grid width.
public int MaxColumns { get; set; } = 200;
}
}