const std = @import("std");
const jetzig = @import("jetzig");

pub const layout = "panel";

const Blog = @import("blogs.zig").Blog;
const Tag = @import("blogs.zig").Tag;

pub fn filterBlogs(allocator: std.mem.Allocator, req: *jetzig.Request, tag_str: []const u8) ![]Blog {
    var blogs: std.AutoArrayHashMapUnmanaged(i32, Blog) = .empty;
    var tag_names = std.mem.splitScalar(u8, tag_str, ',');

    while (tag_names.next()) |tag_name| {
        const query = jetzig.database.Query(.Tag)
            .findBy(.{ .name = tag_name })
            .include(.blog_tags, .{});

        const tag = try req.repo.execute(query) orelse continue;
        for (tag.blog_tags) |blog_tag| {
            const blog = try @import("blogs.zig").fetchBlog(allocator, req, blog_tag.blog_id);
            try blogs.put(allocator, blog.id, blog);
        }
    }

    std.debug.print("blogs: {any}\n", .{blogs.values()});
    return blogs.values();
}

pub fn index(request: *jetzig.Request) !jetzig.View {
    var root = try request.data(.object);

    const query = jetzig.database.Query(.Tag)
        .orderBy(.{ .name = .asc });
    const tags = try request.repo.all(query);

    try root.put("tags", tags);

    const cookies = try request.cookies();
    const allowed = blk: {
        const session = cookies.get("session") orelse break :blk false;

        const session_query = jetzig.database.Query(.Session)
            .findBy(.{ .session_id = session.value });
        _ = request.repo.execute(session_query) catch break :blk false;
        break :blk true;
    };

    try root.put("allowed", allowed);

    return request.render(.ok);
}

pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
    var root = try request.data(.object);

    const blogs =
        try filterBlogs(request.allocator, request, id);

    try root.put("blogs", blogs);

    const cookies = try request.cookies();
    const allowed = blk: {
        const session = cookies.get("session") orelse break :blk false;

        const session_query = jetzig.database.Query(.Session)
            .findBy(.{ .session_id = session.value });
        _ = request.repo.execute(session_query) catch break :blk false;
        break :blk true;
    };

    try root.put("allowed", allowed);

    return request.render(.ok);
}

// tags/:id/edit
pub fn edit(id: []const u8, request: *jetzig.Request) !jetzig.View {
    // check "session" cookie for authentication
    const cookies = try request.cookies();
    const session = cookies.get("session") orelse {
        return request.fail(.not_found);
    };

    const session_query = jetzig.database.Query(.Session)
        .findBy(.{ .session_id = session.value });

    _ = request.repo.execute(session_query) catch {
        return request.fail(.not_found);
    };

    switch (request.method) {
        .GET => {
            // get tag
            const tag_query = jetzig.database.Query(.Tag)
                .findBy(.{ .name = id });

            const tag = request.repo.execute(tag_query) catch {
                return request.fail(.not_found);
            };

            const root = try request.data(.object);
            try root.put("allowed", true);
            try root.put("tag", tag);

            return request.render(.ok);
        },
        .POST => {
            const params = try request.params();

            const tag_query_original = jetzig.database.Query(.Tag)
                .findBy(.{ .name = id });

            if (try request.repo.execute(tag_query_original)) |tag| {
                const name = params.getT(.string, "name") orelse tag.name;
                const emoji = params.getT(.string, "emoji") orelse tag.emoji;

                const tag_query = jetzig.database.Query(.Tag)
                    .update(.{ .name = name, .emoji = emoji })
                    .where(.{ .id = tag.id });

                try request.repo.execute(tag_query);

                return request.redirect("/tags", .moved_permanently);
            } else {
                return request.fail(.not_found);
            }
        },
        else => return request.fail(.not_found),
    }
}

pub fn delete(id: []const u8, request: *jetzig.Request) !jetzig.View {
    // check "session" cookie for authentication
    const cookies = try request.cookies();
    const session = cookies.get("session") orelse {
        return request.fail(.not_found);
    };
    const session_query = jetzig.database.Query(.Session)
        .findBy(.{ .session_id = session.value });
    _ = request.repo.execute(session_query) catch {
        return request.fail(.not_found);
    };

    const tag_query = jetzig.database.Query(.Tag)
        .findBy(.{ .name = id });

    if (try request.repo.execute(tag_query)) |tag| {
        try request.repo.Query(.BlogTag)
            .deleteAll()
            //.where(.{ .tag_id = tag.id })
            .execute(request.repo);

        try request.repo.delete(tag);
    }

    return request.render(.ok);
}
