using System.Text.Json.Serialization;

namespace Apollinare.API.Services.Reports;

/// <summary>
/// Modelli per il metalinguaggio APRT (Apollinare Report Template)
/// </summary>

public class AprtTemplate
{
    [JsonPropertyName("version")]
    public string Version { get; set; } = "1.0";

    [JsonPropertyName("meta")]
    public AprtMeta Meta { get; set; } = new();

    [JsonPropertyName("resources")]
    public AprtResources Resources { get; set; } = new();

    [JsonPropertyName("dataSources")]
    public Dictionary<string, AprtDataSource> DataSources { get; set; } = new();

    [JsonPropertyName("sections")]
    public List<AprtSection> Sections { get; set; } = new();

    [JsonPropertyName("pages")]
    public List<AprtPage> Pages { get; set; } = new();

    [JsonPropertyName("elements")]
    public List<AprtElement> Elements { get; set; } = new();
}

/// <summary>
/// Represents a single page in a multi-page template.
/// Each page can optionally override the template's default page settings.
/// </summary>
public class AprtPage
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("pageSize")]
    public string? PageSize { get; set; } // Override template default

    [JsonPropertyName("orientation")]
    public string? Orientation { get; set; } // Override template default

    [JsonPropertyName("margins")]
    public AprtMargins? Margins { get; set; } // Override template default

    [JsonPropertyName("backgroundColor")]
    public string? BackgroundColor { get; set; }
}

public class AprtMeta
{
    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("description")]
    public string? Description { get; set; }

    [JsonPropertyName("author")]
    public string? Author { get; set; }

    [JsonPropertyName("createdAt")]
    public string? CreatedAt { get; set; }

    [JsonPropertyName("pageSize")]
    public string PageSize { get; set; } = "A4";

    [JsonPropertyName("orientation")]
    public string Orientation { get; set; } = "portrait";

    [JsonPropertyName("margins")]
    public AprtMargins Margins { get; set; } = new();
}

public class AprtMargins
{
    [JsonPropertyName("top")]
    public float Top { get; set; } = 20;

    [JsonPropertyName("right")]
    public float Right { get; set; } = 15;

    [JsonPropertyName("bottom")]
    public float Bottom { get; set; } = 20;

    [JsonPropertyName("left")]
    public float Left { get; set; } = 15;
}

public class AprtResources
{
    [JsonPropertyName("fonts")]
    public List<AprtFontResource> Fonts { get; set; } = new();

    [JsonPropertyName("images")]
    public List<AprtImageResource> Images { get; set; } = new();
}

public class AprtFontResource
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("url")]
    public string? Url { get; set; }

    [JsonPropertyName("data")]
    public string? Data { get; set; } // Base64 encoded
}

public class AprtImageResource
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("url")]
    public string? Url { get; set; }

    [JsonPropertyName("data")]
    public string? Data { get; set; } // Base64 encoded
}

public class AprtDataSource
{
    [JsonPropertyName("type")]
    public string Type { get; set; } = "object"; // object | array

    [JsonPropertyName("schema")]
    public string Schema { get; set; } = string.Empty;
}

public class AprtSection
{
    [JsonPropertyName("id")]
    public string? Id { get; set; }

    [JsonPropertyName("type")]
    public string Type { get; set; } = "body"; // header | body | detail | footer

    [JsonPropertyName("height")]
    public float? Height { get; set; }

    [JsonPropertyName("repeatOnPages")]
    public bool RepeatOnPages { get; set; } = false;

    [JsonPropertyName("dataSource")]
    public string? DataSource { get; set; }

    [JsonPropertyName("elements")]
    public List<string> Elements { get; set; } = new(); // Element IDs
}

public class AprtElement
{
    [JsonPropertyName("id")]
    public string Id { get; set; } = string.Empty;

    [JsonPropertyName("type")]
    public string Type { get; set; } = "text"; // text | image | shape | table | line | barcode

    [JsonPropertyName("section")]
    public string? Section { get; set; } // header | body | footer

    [JsonPropertyName("pageId")]
    public string? PageId { get; set; } // ID of the page this element belongs to

    [JsonPropertyName("position")]
    public AprtPosition Position { get; set; } = new();

    [JsonPropertyName("style")]
    public AprtStyle Style { get; set; } = new();

    [JsonPropertyName("content")]
    public AprtContent? Content { get; set; }

    [JsonPropertyName("imageSettings")]
    public AprtImageSettings? ImageSettings { get; set; }

    [JsonPropertyName("dataSource")]
    public string? DataSource { get; set; }

    [JsonPropertyName("columns")]
    public List<AprtTableColumn>? Columns { get; set; }

    [JsonPropertyName("visible")]
    public bool Visible { get; set; } = true;

    [JsonPropertyName("locked")]
    public bool Locked { get; set; } = false;

    [JsonPropertyName("name")]
    public string? Name { get; set; }
}

public class AprtImageSettings
{
    [JsonPropertyName("src")]
    public string? Src { get; set; }

    [JsonPropertyName("originalWidth")]
    public int? OriginalWidth { get; set; }

    [JsonPropertyName("originalHeight")]
    public int? OriginalHeight { get; set; }

    [JsonPropertyName("fitMode")]
    public string FitMode { get; set; } = "contain"; // contain | cover | fill | none

    [JsonPropertyName("maintainAspectRatio")]
    public bool MaintainAspectRatio { get; set; } = true;

    [JsonPropertyName("horizontalAlign")]
    public string HorizontalAlign { get; set; } = "center";

    [JsonPropertyName("verticalAlign")]
    public string VerticalAlign { get; set; } = "center";

    [JsonPropertyName("opacity")]
    public float Opacity { get; set; } = 1;

    [JsonPropertyName("borderRadius")]
    public float BorderRadius { get; set; } = 0;

    [JsonPropertyName("shadow")]
    public bool Shadow { get; set; } = false;

    [JsonPropertyName("flipHorizontal")]
    public bool FlipHorizontal { get; set; } = false;

    [JsonPropertyName("flipVertical")]
    public bool FlipVertical { get; set; } = false;
}

public class AprtPosition
{
    [JsonPropertyName("x")]
    public float X { get; set; }

    [JsonPropertyName("y")]
    public float Y { get; set; }

    [JsonPropertyName("width")]
    public float Width { get; set; } = 100;

    [JsonPropertyName("height")]
    public float Height { get; set; } = 20;

    [JsonPropertyName("rotation")]
    public float Rotation { get; set; } = 0;
}

public class AprtStyle
{
    [JsonPropertyName("fontFamily")]
    public string FontFamily { get; set; } = "Helvetica";

    [JsonPropertyName("fontSize")]
    public float FontSize { get; set; } = 12;

    [JsonPropertyName("fontWeight")]
    public string FontWeight { get; set; } = "normal"; // normal | bold

    [JsonPropertyName("fontStyle")]
    public string FontStyle { get; set; } = "normal"; // normal | italic

    [JsonPropertyName("color")]
    public string Color { get; set; } = "#000000";

    [JsonPropertyName("backgroundColor")]
    public string? BackgroundColor { get; set; }

    [JsonPropertyName("textAlign")]
    public string TextAlign { get; set; } = "left"; // left | center | right | justify

    [JsonPropertyName("verticalAlign")]
    public string VerticalAlign { get; set; } = "top"; // top | middle | bottom

    [JsonPropertyName("borderWidth")]
    public float BorderWidth { get; set; } = 0;

    [JsonPropertyName("borderColor")]
    public string BorderColor { get; set; } = "#000000";

    [JsonPropertyName("borderStyle")]
    public string BorderStyle { get; set; } = "solid"; // solid | dashed | dotted

    [JsonPropertyName("padding")]
    public float Padding { get; set; } = 0;

    [JsonPropertyName("lineHeight")]
    public float LineHeight { get; set; } = 1.2f;

    [JsonPropertyName("opacity")]
    public float Opacity { get; set; } = 1;
}

public class AprtContent
{
    [JsonPropertyName("type")]
    public string Type { get; set; } = "static"; // static | binding | expression | resource

    [JsonPropertyName("value")]
    public string? Value { get; set; }

    [JsonPropertyName("expression")]
    public string? Expression { get; set; }

    [JsonPropertyName("resourceId")]
    public string? ResourceId { get; set; }

    [JsonPropertyName("format")]
    public string? Format { get; set; } // currency | date | number | percent

    [JsonPropertyName("formatOptions")]
    public Dictionary<string, object>? FormatOptions { get; set; }
}

public class AprtTableColumn
{
    [JsonPropertyName("field")]
    public string Field { get; set; } = string.Empty;

    [JsonPropertyName("header")]
    public string Header { get; set; } = string.Empty;

    [JsonPropertyName("width")]
    public float Width { get; set; } = 100;

    [JsonPropertyName("format")]
    public string? Format { get; set; }

    [JsonPropertyName("align")]
    public string Align { get; set; } = "left";

    [JsonPropertyName("headerStyle")]
    public AprtStyle? HeaderStyle { get; set; }

    [JsonPropertyName("cellStyle")]
    public AprtStyle? CellStyle { get; set; }
}

// DTOs per l'API
public class GenerateReportRequest
{
    public int TemplateId { get; set; }
    public Dictionary<string, object> DataContext { get; set; } = new();
}

public class ReportTemplateDto
{
    public int Id { get; set; }
    public string Nome { get; set; } = string.Empty;
    public string? Descrizione { get; set; }
    public string Categoria { get; set; } = "Generale";
    public string TemplateJson { get; set; } = "{}";
    public string? ThumbnailBase64 { get; set; }
    public string PageSize { get; set; } = "A4";
    public string Orientation { get; set; } = "portrait";
    public bool Attivo { get; set; } = true;
    public DateTime? CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }
}

public class ReportFontDto
{
    public int Id { get; set; }
    public string Nome { get; set; } = string.Empty;
    public string FontFamily { get; set; } = string.Empty;
    public string FontStyle { get; set; } = "Regular";
    public string? FontDataBase64 { get; set; }
    public string MimeType { get; set; } = "font/ttf";
    public long FileSize { get; set; }
    public bool Attivo { get; set; } = true;
}

public class ReportImageDto
{
    public int Id { get; set; }
    public string Nome { get; set; } = string.Empty;
    public string Categoria { get; set; } = "Generale";
    public string? ImageDataBase64 { get; set; }
    public string MimeType { get; set; } = "image/png";
    public int Width { get; set; }
    public int Height { get; set; }
    public long FileSize { get; set; }
    public bool Attivo { get; set; } = true;
}
