const std = @import("std");

const utils = @import("utils");

const Dimensions = @import("../../../Dimensions.zig");
const escaper = @import("../../../escaper.zig");
const api = @import("../../../api/root.zig");

pub const Title = struct {
    title_name: []const u8,
    artists: []const []const u8,
    album_name: ?[]const u8,
    album_cover_url: ?[]const u8,

    pub fn escape(self: *const Title, allocator: std.mem.Allocator) !utils.ResultArena(Title) {
        var result = utils.ResultArena(Title){
            .arena = try allocator.create(std.heap.ArenaAllocator),
            .value = undefined,
        };
        errdefer allocator.destroy(result.arena);
        result.arena.* = std.heap.ArenaAllocator.init(allocator);
        errdefer result.arena.deinit();

        const title_name = try escaper.escapeHtml(result.arena.allocator(), self.title_name);
        result.value.title_name = title_name orelse self.title_name;

        const artists = try result.arena.allocator().alloc([]const u8, self.artists.len);
        for (self.artists, 0..) |artist, i| {
            const escaped = try escaper.escapeHtml(result.arena.allocator(), artist);
            artists[i] = escaped orelse artist;
        }
        result.value.artists = artists;

        result.value.album_name = null;
        if (self.album_name) |str| {
            const album_name = try escaper.escapeHtml(result.arena.allocator(), str);
            result.value.album_name = album_name orelse str;
        }

        result.value.album_cover_url = null;
        if (self.album_cover_url) |str| {
            const album_cover_url = try escaper.escapeHtml(result.arena.allocator(), str);
            result.value.album_cover_url = album_cover_url orelse str;
        }

        return result;
    }
};

pub const Context = struct {
    title: ?Title,

    pub fn escape(self: *const Context, allocator: std.mem.Allocator) !utils.ResultArena(Context) {
        var result = utils.ResultArena(Context){
            .arena = try allocator.create(std.heap.ArenaAllocator),
            .value = undefined,
        };
        errdefer allocator.destroy(result.arena);
        result.arena.* = std.heap.ArenaAllocator.init(allocator);
        errdefer result.arena.deinit();

        result.value.title = null;
        if (self.title) |title| {
            const escaped = try title.escape(result.arena.allocator());
            errdefer escaped.deinit();
            result.value.title = escaped.value;
        }

        return result;
    }
};

pub fn render(dimensions: Dimensions, context: *const Context, writer: std.io.AnyWriter) !void {
    try writer.writeAll(
        \\<!doctype html>
        \\<html lang="en">
        \\  <head>
        \\    <meta charset="UTF-8" />
    );
    try writer.print(
        \\<meta
        \\  name="viewport"
        \\  content="width={[width]d}, height={[height]d}, initial-scale=1.0, user-scalable=no"
        \\/>
    ,
        .{ .width = dimensions.width, .height = dimensions.height },
    );
    try writer.print(
        \\<style>{[fonts_css]s}</style>
        \\<style>{[style_css]s}</style>
        \\<style>
        \\  html,
        \\  body {{
        \\    width: {[width]d}px;
        \\    height: {[height]d}px;
        \\  }}
        \\</style>
    ,
        .{
            .fonts_css = @embedFile("css/fonts.css.dat"),
            .style_css = @embedFile("css/style.css"),
            .width = dimensions.width,
            .height = dimensions.height,
        },
    );
    try writer.writeAll(
        \\</head>
    );

    try writer.writeAll(
        \\<body>
        \\  <div id="wrapper">
    );

    if (context.title) |title| {
        try writer.print(
            \\<img id="album-cover" src="{[album_cover_url]s}" />
            \\<div id="title">
            \\  <h1 id="title-name">{[title_name]s}</h1>
            \\  <h2 id="album-name">{[album_name]s}</h2>
            \\  <h2 id="artists">
        ,
            .{
                .album_cover_url = title.album_cover_url orelse "",
                .title_name = title.title_name,
                .album_name = title.album_name orelse "",
            },
        );
        for (title.artists, 0..) |artist, i| {
            try writer.print(
                \\<span>{s}</span>
            ,
                .{artist},
            );
            if (i < title.artists.len - 1) {
                try writer.writeAll(
                    \\,&nbsp;
                );
            }
        }
        try writer.writeAll(
            \\  </h2>
            \\</div>
        );
    }

    try writer.writeAll(
        \\    </div>
        \\  </body>
        \\</html>
    );
}
