#include <imgui.h>
#include <imgui_internal.h>

#include "inter.h"

int year = 2025;

bool is_leap_year(int year) {
    return  ((year % 4) == 0 && (year % 100) != 0) || year % 400 == 0;
}

int weekday_from_day(int year, int month, int day) {
    int a = (14 - month) / 12;
    int y = year - a;
    int m = month + (12 * a) - 2;
    return (day + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12) - 1) % 7;
}

int calendar_week_from_day(int year, int month, int day){
    int days_sum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
    int days = days_sum[month - 1];
    if(is_leap_year(year) && month > 2)
        days++;
    
    return (10 + days + day - weekday_from_day(year, month, day)) / 7;
}

int days_per_month(int year, int month){
    int days_in_month[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    if (month == 2) {
        return is_leap_year(year) ? 29 : 28;
    }
    return days_in_month[month - 1];
}

void init(){
    ImGuiIO &io = ImGui::GetIO();
    io.Fonts->AddFontFromMemoryCompressedTTF(inter_compressed_data, inter_compressed_size);
}

void per_frame(){
    static bool use_work_area = true;
    static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings;
    // We demonstrate using the full viewport area or the work area (without menu-bars, task-bars etc.)
    const ImGuiViewport* viewport = ImGui::GetMainViewport();
    ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos);
    ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize : viewport->Size);

    ImGuiStyle& style = ImGui::GetStyle();
    auto default_item_spacing = style.ItemSpacing;

    const char* month_names[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};

    //
    ImGui::Begin("Work Calendar", 0, flags);

    ImGui::PushStyleColor(ImGuiCol_TableHeaderBg, {0,0,0,0});
    ImGui::PushStyleColor(ImGuiCol_HeaderHovered, {0,0,0,0});
    ImGui::PushStyleColor(ImGuiCol_HeaderActive, {0,0,0,0});

    if(ImGui::BeginTable("Calendar", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX)) {
        ImGui::TableNextRow();
        ImGui::TableSetColumnIndex(0);

        ImGui::BeginGroup();
        if (ImGui::ArrowButton("##left", ImGuiDir_Left)) 
            year--;
        ImGui::SameLine(0, 0);

        if (ImGui::ArrowButton("##right", ImGuiDir_Right))  
            year++; 
        ImGui::SameLine(0, 0);
        
        ImGui::TextAligned(0.5, -FLT_MIN, "%d", year);  
        ImGui::EndGroup();

        ImGui::TableNextRow();
        ImGui::TableSetColumnIndex(0);

        for (int month = 1; month <= 12; month++) {
            ImGui::PushID(month);
            ImGui::PushStyleColor(ImGuiCol_TableBorderStrong, {0,0,0,0});
            ImGui::PushStyleColor(ImGuiCol_TableBorderLight, {0,0,0,0});

            if(ImGui::BeginTable("Month", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX)) {
                ImGui::TableNextRow();
                ImGui::TableSetColumnIndex(0);
                ImGui::TextAligned(0.5, -FLT_MIN, month_names[month - 1]);

                ImGui::TableNextRow();
                ImGui::TableSetColumnIndex(0);

                //calendar week table
                if(ImGui::BeginTable("CalendarWeek", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)){
                    ImGui::TableNextRow();
                    ImGui::TableSetColumnIndex(0);
                    ImGui::TextAligned(0.5, -FLT_MIN, "KW");

                    for (int day = 1; day <= days_per_month(year, month); day++) {
                        int weekday = weekday_from_day(year, month, day);

                        if(weekday == 0 || day == 1){
                            ImGui::TableNextRow();
                            ImGui::TableSetColumnIndex(0);

                            //if first week has 3 or less days, last week from previous year
                            int calender_week = calendar_week_from_day(year, month, day);
                            if(calender_week == 0) {
                                ImGui::TextAligned(0.5, -FLT_MIN, "%d", 53);
                            } else {
                                ImGui::TextAligned(0.5, -FLT_MIN, "%d", calender_week);
                            }
                        }
                    }

                    ImGui::EndTable();
                }
                ImGui::SameLine(0, 0);

                ImGui::BeginGroup();
                ImGui::PushStyleVarY(ImGuiStyleVar_ItemSpacing, 0);

                if(ImGui::BeginTable("Weekdays", 7, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)){

                    ImGui::TableSetupColumn("Mo");
                    ImGui::TableSetupColumn("Di");
                    ImGui::TableSetupColumn("Mi");
                    ImGui::TableSetupColumn("Do");
                    ImGui::TableSetupColumn("Fr");
                    ImGui::TableSetupColumn("Sa");
                    ImGui::TableSetupColumn("So");
                    ImGui::TableHeadersRow();

                    ImGui::EndTable();
                }
                ImGui::PopStyleColor(2);

                ImGui::PushStyleColor(ImGuiCol_TableBorderStrong, {119/255.0f,119/255.0f,119/255.0f,83/255.0f});
                ImGui::PushStyleColor(ImGuiCol_TableBorderLight, {119/255.0f,119/255.0f,119/255.0f,83/255.0f});

                //days of month table
                if(ImGui::BeginTable("Weekdays", 7, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_Borders)) {
                    int offset = weekday_from_day(year, month, 1);

                    for (int day = 1; day <= days_per_month(2025, month); day++) {
                        int weekday = weekday_from_day(year, month, day);

                        if(weekday == 0 || day == 1){
                            ImGui::TableNextRow();
                        }

                        ImGui::TableSetColumnIndex(weekday);
                        ImU32 cell_bg_color_workweek = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
                        ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_workweek);

                        //weekend coloring
                        if(weekday == 5){
                            ImU32 cell_bg_color_sat = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.1f));
                            ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_sat);
                        }

                        if(weekday == 6){
                            ImU32 cell_bg_color_sun = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 0.2f));
                            ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color_sun);
                        }
                        
                        ImGui::TextAligned(0.5, -FLT_MIN, "%d", day);
                    }

                    ImGui::EndTable();
                }
                ImGui::PopStyleColor(2);
                ImGui::PopStyleVar();
                //weekday header table + days of month table
                ImGui::EndGroup();
                //month table
                ImGui::EndTable();
            }

            if ((month % 4) != 0)
                ImGui::SameLine();

            ImGui::PopID();
        }
        //calendar table
        ImGui::EndTable();
    }

    ImGui::PopStyleColor(3);

    ImGui::End();
}

