#include "common.h"

// Save character data to files
static void SaveData(int *attrs, int *skills, int *base_stats)
{
    FILE *fw = fopen("saves/skills.txt","w");
    if(fw){ for(int i=0;i<SKILL_COUNT;i++) fprintf(fw,"%d ",skills[i]); fclose(fw); }
    fw = fopen("saves/attributes.txt","w");
    if(fw){ for(int i=0;i<ATTRIBUTES_COUNT;i++) fprintf(fw,"%d ",attrs[i]); fclose(fw); }
    fw = fopen("saves/stats.txt","w");
    if(fw){ for(int i=0;i<STATS_COUNT;i++) fprintf(fw,"%d ",base_stats[i]); fclose(fw); }
}

static void SavePlayerStats(int level, int xp, int cp)
{
    FILE *fw = fopen("saves/player_stats.txt","w");
    if(fw){ fprintf(fw,"%d %d %d",level,xp,cp); fclose(fw); }
}

// Tab bar, header, footer
static void DrawTabs(int *current_tab, bool edit_mode, bool player_edit_mode, bool clickable)
{
    DrawRectangle(0,110,192,490,C_PANEL);                                        // CHANGED: width 216->192
    DrawLine(192,110,192,600,C_BORDER);                                          // CHANGED: x 216->192
    for(int i=0;i<TAB_COUNT;i++){
        int ty=118+i*46;
        bool active=(i==*current_tab);
        bool hov=CheckCollisionPointRec(GetMousePosition(),(Rectangle){0,(float)ty,192,38}); // CHANGED: 216->192
        Color bg  = active?C_PANEL3:hov?C_PANEL2:C_PANEL;
        Color txt = active?C_GOLD_L:C_TEXT;
        DrawRectangle(0,ty,192,38,bg);                                           // CHANGED: 216->192
        if(active){
            DrawRectangle(0,ty,4,38,C_GOLD);
            if(edit_mode||player_edit_mode) DrawRectangle(188,ty,4,38,C_GOLD);  // CHANGED: 212->188
        }
        DrawText(tab_names[i],18,ty+10,18,txt);
        if(active&&edit_mode)
            Badge(MeasureText(tab_names[i],18)+26,ty+9,"EDIT",C_GOLD_D,C_GOLD_L);

        if(clickable&&hov&&i!=*current_tab&&IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
            *current_tab=i;
            if(*current_tab!=4){ quest_create=false; quest_view=-1; }
        }
    }
}

static void DrawHeader(int level, int xp, int cp, int tnl_cur, bool player_edit_mode, int sel_ps)
{
    DrawRectangle(0,0,900,108,C_HEADER);
    DrawLine(0,108,900,108,C_BORDER);
    DrawRectangle(0,0,4,108,C_GOLD);

    DrawText("VAELEN",22,14,28,C_GOLD_L);
    DrawText("\"S_Lord\"",22,46,14,C_MUTED);

    Color c_lv=(player_edit_mode&&sel_ps==0)?C_GOLD_L:C_TEXT;
    char lvs[32]; snprintf(lvs,sizeof(lvs),"LEVEL  %d",level);
    Badge(200,18,lvs,player_edit_mode&&sel_ps==0?C_GOLD_D:C_PANEL3,c_lv);

    Color c_xp=(player_edit_mode&&sel_ps==1)?C_GOLD_L:C_TEXT;
    DrawText(TextFormat("XP  %d / %d",xp,tnl_cur>0?tnl_cur:0),200,46,14,c_xp);

    float prog=tnl_cur>0?(float)xp/(float)tnl_cur:0.f;
    if(prog>1.f)prog=1.f;
    ProgBar((Rectangle){200,68,340,8},prog,C_GOLD);

    Color c_cp=(player_edit_mode&&sel_ps==2)?C_GOLD_L:C_TEXT;
    char cps[32]; snprintf(cps,sizeof(cps),"CP  %d",cp);
    Badge(580,18,cps,player_edit_mode&&sel_ps==2?C_GOLD_D:C_PANEL3,c_cp);
}

static void DrawFooter(bool edit_mode, bool player_edit_mode)
{
    DrawRectangle(0,572,900,28,C_HEADER);
    DrawLine(0,572,900,572,C_BORDER);
    const char *info;
    if(player_edit_mode)   info="[ p ] TAB EDIT   |   [ O ] EXIT PLAYER EDIT   |   [ F11 ] FULLSCREEN";
    else if(edit_mode)     info="[ P ] EXIT TAB EDIT   |   [ O ] PLAYER EDIT   |   [ F11 ] FULLSCREEN";
    else                   info="[ P ] TAB EDIT   |   [ O ] PLAYER EDIT   |   [ F11 ] FULLSCREEN";
    DrawText(info,14,578,13,C_MUTED);
}

// Main
int main(void)
{
    int skills[SKILL_COUNT]          = {0};
    int attributes[ATTRIBUTES_COUNT] = {0};
    int tnl[MAX_LEVEL]               = {0};
    int base_stats[STATS_COUNT]      = {0};
    int gear_stats[STATS_COUNT]      = {0};
    int effective_stats[STATS_COUNT] = {0};   // base + gear, used wherever the player's real stat total matters (e.g. guild requirements)

    int xp=1673, level=4, cp=1650;
    int selected_stat=0, selected_skill=0, selected_attr=0;
    int edit_mode=0, player_edit_mode=0;
    int selected_player_stat=0;
    int current_tab=0;

    SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
    InitWindow(DEFAULT_WIN_W,DEFAULT_WIN_H,"Aetheria — Character Menu");
    SetWindowMinSize(720,480);
    SetExitKey(KEY_NULL);
    SetTargetFPS(60);
    srand((unsigned)time(NULL));

    // The entire UI is drawn at the fixed VWxVH "design" resolution into this
    // off-screen buffer, then scaled (letterboxed) to fit the actual window.
    // This keeps every hard-coded 900x600 coordinate valid at any window size.
    RenderTexture2D screen = LoadRenderTexture(VW,VH);
    SetTextureFilter(screen.texture, TEXTURE_FILTER_BILINEAR);
    int winW=DEFAULT_WIN_W, winH=DEFAULT_WIN_H;   // remembered windowed size for clean F11 toggling

    // Load data from files
    FILE *lvlfile=fopen("levels/levels.txt","r");
    if(lvlfile){ for(int i=0;i<MAX_LEVEL;i++) fscanf(lvlfile,"%d",&tnl[i]); fclose(lvlfile); }
    FILE *f=fopen("saves/skills.txt","r");
    if(f){ for(int i=0;i<SKILL_COUNT;i++) fscanf(f,"%d",&skills[i]); fclose(f); }
    f=fopen("saves/attributes.txt","r");
    if(f){ for(int i=0;i<ATTRIBUTES_COUNT;i++) fscanf(f,"%d",&attributes[i]); fclose(f); }
    FILE *fs=fopen("saves/stats.txt","r");
    if(fs){ for(int i=0;i<STATS_COUNT;i++) fscanf(fs,"%d",&base_stats[i]); fclose(fs); }
    FILE *fps=fopen("saves/player_stats.txt","r");
    if(fps){ fscanf(fps,"%d %d %d",&level,&xp,&cp); fclose(fps); }
    QuestLoad();
    QuestGenInit();
    ChainLoad();
    LoadClassState();
    EnsureNamePool();
    GuildLoad();

    while(!WindowShouldClose()){
        float dt=GetFrameTime();

        // ---- Window scaling & F11 fullscreen -------------------------------
        if(IsKeyPressed(KEY_F11)){
            if(!IsWindowFullscreen()){
                winW=GetScreenWidth(); winH=GetScreenHeight();
                int mon=GetCurrentMonitor();
                SetWindowSize(GetMonitorWidth(mon),GetMonitorHeight(mon));
                ToggleFullscreen();
            } else {
                ToggleFullscreen();
                SetWindowSize(winW,winH);
            }
        }
        float scrW=(float)GetScreenWidth(), scrH=(float)GetScreenHeight();
        float scale=fminf(scrW/(float)VW, scrH/(float)VH);
        if(scale<0.1f) scale=0.1f;
        float offX=(scrW-(float)VW*scale)*0.5f;
        float offY=(scrH-(float)VH*scale)*0.5f;
        // Report mouse coordinates in design (VWxVH) space to all existing UI code
        SetMouseOffset((int)(-offX),(int)(-offY));
        SetMouseScale(1.f/scale,1.f/scale);

        for(int i=0;i<STATS_COUNT;i++) gear_stats[i]=base_stats[i];
        for(int i=0;i<STATS_COUNT;i++) effective_stats[i]=base_stats[i]+gear_stats[i];

        // Auto-calculate cls_totalXP every frame
        UpdateTotalXP(level, xp, tnl);

        bool quest_modal_open = (current_tab==4)&&(quest_create||quest_view>=0||ChainModalOpen());
        bool class_modal_open = (current_tab==3)&&showModal;
        bool guild_sub_open   = (current_tab==5)&&(guild_view!=0);
        bool any_modal_open   = quest_modal_open||class_modal_open||guild_sub_open;

        // ESC closes any open modal / guild sub-view
        if(IsKeyPressed(KEY_ESCAPE)){
            if(current_tab==3&&showModal)               CancelClassModal();
            else if(current_tab==4&&quest_create)       quest_create=false;
            else if(current_tab==4&&quest_view>=0)      quest_view=-1;
            else if(current_tab==4&&ChainModalOpen())   ChainHandleEscape();
            else if(current_tab==5&&guild_req_modal>=0) guild_req_modal=-1;
            else if(current_tab==5&&guild_view!=0)      GuildHandleEscape();
        }

        // Global shortcuts (blocked while a modal is open)
        if(!any_modal_open){
            if(IsKeyPressed(KEY_O)){
                player_edit_mode=!player_edit_mode;
                if(player_edit_mode) edit_mode=0;
            }
            if(IsKeyPressed(KEY_P)){
                if(current_tab==0||current_tab==1||current_tab==2){
                    edit_mode=!edit_mode;
                    if(edit_mode) player_edit_mode=0;
                }
            }
        }

        // Player-stats edit mode
        if(player_edit_mode&&!any_modal_open){
            bool p_changed=false;
            static float hold_timer=0.f;

            if(IsKeyPressed(KEY_UP))   selected_player_stat=selected_player_stat>0?selected_player_stat-1:2;
            if(IsKeyPressed(KEY_DOWN)) selected_player_stat=selected_player_stat<2?selected_player_stat+1:0;

            long long base_inc=1;
            if(IsKeyDown(KEY_LEFT_SHIFT)||IsKeyDown(KEY_RIGHT_SHIFT))     base_inc=100;
            if(IsKeyDown(KEY_LEFT_CONTROL)||IsKeyDown(KEY_RIGHT_CONTROL)) base_inc=10000;
            int dir=0;
            if(IsKeyDown(KEY_RIGHT)) dir= 1;
            if(IsKeyDown(KEY_LEFT))  dir=-1;
            if(dir!=0){
                hold_timer+=dt;
                if(IsKeyPressed(KEY_RIGHT)||IsKeyPressed(KEY_LEFT)){
                    if     (selected_player_stat==0) level=dir>0?(level<MAX_LEVEL-1?level+1:level):(level>0?level-1:0);
                    else if(selected_player_stat==1) xp+=(int)(base_inc*dir);
                    else if(selected_player_stat==2) cp+=(int)(base_inc*dir);
                    p_changed=true;
                }
                if(hold_timer>0.6f&&selected_player_stat!=0){
                    float acc=hold_timer>5.f?100.f:hold_timer>3.f?10.f:1.f;
                    long long amt=(long long)(base_inc*acc*dir);
                    if(selected_player_stat==1) xp+=(int)amt;
                    else if(selected_player_stat==2) cp+=(int)amt;
                    p_changed=true;
                }
            } else hold_timer=0.f;
            if(xp<0) xp=0;
            if(cp<0) cp=0;
            if(p_changed) SavePlayerStats(level,xp,cp);

        // Tab navigation and content editing
        } else if(!player_edit_mode&&!any_modal_open){
            if(IsKeyPressed(KEY_UP)){
                if(!edit_mode){
                    current_tab=current_tab>0?current_tab-1:TAB_COUNT-1;
                    if(current_tab!=4){ quest_create=false; quest_view=-1; }
                } else {
                    if(current_tab==0) selected_stat =selected_stat >0?selected_stat -1:STATS_COUNT-1;
                    if(current_tab==1) selected_attr =selected_attr >0?selected_attr -1:ATTRIBUTES_COUNT-1;
                    if(current_tab==2) selected_skill=selected_skill>0?selected_skill-1:SKILL_COUNT-1;
                }
            }
            if(IsKeyPressed(KEY_DOWN)){
                if(!edit_mode){
                    current_tab=current_tab<TAB_COUNT-1?current_tab+1:0;
                    if(current_tab!=4){ quest_create=false; quest_view=-1; }
                } else {
                    if(current_tab==0) selected_stat =selected_stat <STATS_COUNT-1     ?selected_stat +1:0;
                    if(current_tab==1) selected_attr =selected_attr <ATTRIBUTES_COUNT-1?selected_attr +1:0;
                    if(current_tab==2) selected_skill=selected_skill<SKILL_COUNT-1     ?selected_skill+1:0;
                }
            }
            if(edit_mode){
                bool changed=false;
                bool shiftHeld=(IsKeyDown(KEY_LEFT_SHIFT)||IsKeyDown(KEY_RIGHT_SHIFT));
                bool ctrlHeld =(IsKeyDown(KEY_LEFT_CONTROL)||IsKeyDown(KEY_RIGHT_CONTROL));
                // Stats/Attributes: 1, or 10 with SHIFT.  Skills: 1, 10 with SHIFT, 100 with CTRL.
                int step = shiftHeld?10:1;
                int skillStep = ctrlHeld?100:step;

                // Holding LEFT/RIGHT repeats the step at a constant rate (no acceleration).
                static float valHoldTimer=0.f;
                const float VAL_HOLD_DELAY=0.45f, VAL_HOLD_RATE=0.05f;
                int dir=0;
                if(IsKeyDown(KEY_RIGHT)) dir= 1;
                else if(IsKeyDown(KEY_LEFT)) dir=-1;

                bool fire=false;
                if(dir!=0){
                    if(IsKeyPressed(KEY_RIGHT)||IsKeyPressed(KEY_LEFT)){ fire=true; valHoldTimer=0.f; }
                    else {
                        valHoldTimer+=dt;
                        if(valHoldTimer>=VAL_HOLD_DELAY){ fire=true; valHoldTimer-=VAL_HOLD_RATE; }
                    }
                } else valHoldTimer=0.f;

                if(fire){
                    if(current_tab==0) base_stats[selected_stat]+=step*dir;
                    if(current_tab==1){ attributes[selected_attr]+=step*dir; if(attributes[selected_attr]>100) attributes[selected_attr]=100; }
                    if(current_tab==2){ skills[selected_skill]+=skillStep*dir; if(skills[selected_skill]>1000) skills[selected_skill]=1000; }
                    changed=true;
                }
                if(changed) SaveData(attributes,skills,base_stats);
            }
        }

        // ---- Draw the UI into the fixed-size off-screen buffer ----
        BeginTextureMode(screen);
        ClearBackground(C_BG);

        DrawHeader(level,xp,cp, level<MAX_LEVEL?tnl[level]:0, player_edit_mode,selected_player_stat);
        DrawTabs(&current_tab,edit_mode,player_edit_mode,!player_edit_mode&&!any_modal_open);

        DrawRectangle(193,109,707,463,C_PANEL);
        DrawLine(193,109,193,572,C_BORDER);
        DrawLine(193,572,900,572,C_BORDER);
        int cX=200, cY=122;

        switch(current_tab){
            case 0:  DrawTabStats      (cX,cY,base_stats,gear_stats,selected_stat,edit_mode); break;
            case 1:  DrawTabAttributes (cX,cY,attributes,selected_attr,edit_mode);            break;
            case 2:  DrawTabSkills     (cX,cY,skills,selected_skill,edit_mode);               break;
            case 3:  DrawTabClasses    (cX,cY);                                               break;
            case 4:  DrawTabQuests     (cX,cY,dt,level);                                      break;
            case 5:  DrawTabGuild      (cX,cY,attributes,skills,effective_stats);             break;
            case 9:  DrawTabRegister   (cX,cY,skills);                                        break;
            default: DrawComingSoon    (cX,cY,current_tab);                                   break;
        }

        DrawFooter(edit_mode,player_edit_mode);

        // Overlays — drawn last so they appear on top
        if(current_tab==3 && showModal)         DrawClassModal();
        if(current_tab==4 && quest_create){
            if(quest_tab==0) DrawQuestBuilderModal(dt);
            else             DrawQuestCreateModal(1,dt);
        }
        if(current_tab==4 && quest_view>=0)     DrawQuestViewModal();
        if(current_tab==4 && ChainModalOpen())  DrawChainModals(dt);
        if(current_tab==5 && guild_req_modal>=0) DrawGuildReqModal(attributes,skills,effective_stats);
        DrawNotifToast(dt);

        EndTextureMode();

        // ---- Blit the buffer to the window, scaled and letterboxed ----
        BeginDrawing();
        ClearBackground((Color){4,4,10,255});
        DrawTexturePro(screen.texture,
            (Rectangle){0.f,0.f,(float)VW,-(float)VH},                       // src (Y-flipped)
            (Rectangle){offX,offY,(float)VW*scale,(float)VH*scale},          // dst (letterboxed)
            (Vector2){0.f,0.f}, 0.f, WHITE);
        EndDrawing();
    }

    // Final save on exit
    SaveData(attributes,skills,base_stats);
    SavePlayerStats(level,xp,cp);
    SaveClassState();
    GuildSave();
    UnloadRenderTexture(screen);
    CloseWindow();
    return 0;
}
