#include "common.h"

typedef struct {
    char name[MAX_CLASS_NAME]; int levelCap; int allocatedXP; int levelReqs[MAX_CLASS_LEVELS];
} Class;

// Class state
static int   cls_totalXP  = 0;
static Class classes[MAX_CLASSES];
static int   classCount   = 0;
static int   selectedCls  = -1;
bool         showModal    = false;

static TBox  tbNewName  = {{0}, false};
static int   newCap     = 10;
static TBox  tbDistXP   = {{0}, false};

static float sideScroll   = 0.f;
static float detailScroll = 0.f;

// Save/load class state
static void ClassFname(const Class *c, char *out, int n)
{
    snprintf(out, n, CLASS_LEVELS_DIR "%s_levels.txt", c->name);
    int prefixLen=(int)strlen(CLASS_LEVELS_DIR);
    for(int i=prefixLen; out[i]; i++){
        if(out[i]==' ') out[i]='_';
        out[i]=(char)tolower((unsigned char)out[i]);
    }
}

static void CreateClassFile(const Class *c)
{
    char fn[256]; ClassFname(c, fn, sizeof(fn));
    FILE *f = fopen(fn, "w");
    if(!f) return;
    fprintf(f, "# %s  -  Level XP Requirements\n", c->name);
    fprintf(f, "# Edit the numbers after each colon.\n");
    fprintf(f, "# Level 1 is usually 0 XP (starting level).\n");
    fprintf(f, "# After saving this file, click [Reload] in the app.\n#\n");
    for(int i=0; i<c->levelCap; i++) fprintf(f, "Level %d: 0\n", i+1);
    fclose(f);
}

static void LoadClassFile(Class *c)
{
    char fn[256]; ClassFname(c, fn, sizeof(fn));
    FILE *f = fopen(fn, "r");
    if(!f) return;
    char line[256];
    while(fgets(line, sizeof(line), f)){
        if(line[0]=='#'||line[0]=='\n') continue;
        int lv, xp;
        if(sscanf(line, "Level %d: %d", &lv, &xp)==2 && lv>=1 && lv<=c->levelCap)
            c->levelReqs[lv-1] = xp;
    }
    fclose(f);
}

void SaveClassState(void)
{
    FILE *f = fopen(CLASS_SAVE_FILE, "w");
    if(!f) return;
    fprintf(f, "CLASS_COUNT %d\n", classCount);
    for(int i=0; i<classCount; i++)
        fprintf(f, "CLASS %s|%d|%d\n",
                classes[i].name, classes[i].levelCap, classes[i].allocatedXP);
    fclose(f);
}

void LoadClassState(void)
{
    FILE *f = fopen(CLASS_SAVE_FILE, "r");
    if(!f) return;
    char line[256];
    classCount = 0;
    while(fgets(line, sizeof(line), f)){
        if(strncmp(line,"TOTAL_XP",8)==0){
            // Legacy line — cls_totalXP is now auto-calculated, ignore
        } else if(strncmp(line,"CLASS ",6)==0 && classCount<MAX_CLASSES){
            Class *c = &classes[classCount++];
            memset(c, 0, sizeof(*c));
            for(int j=0; j<MAX_CLASS_LEVELS; j++) c->levelReqs[j]=-1;
            char *p=line+6, *p1=strchr(p,'|'), *p2=p1?strchr(p1+1,'|'):NULL;
            if(p1&&p2){
                int nl=(int)(p1-p); if(nl>=MAX_CLASS_NAME) nl=MAX_CLASS_NAME-1;
                strncpy(c->name,p,nl); c->name[nl]='\0';
                c->levelCap=atoi(p1+1); c->allocatedXP=atoi(p2+1);
            }
            LoadClassFile(c);
        }
    }
    fclose(f);
}

// Class helpers
static int GetLevel(const Class *c)
{
    int lv=0;
    for(int i=0; i<c->levelCap; i++)
        if(c->levelReqs[i]>=0 && c->levelReqs[i]<=c->allocatedXP) lv=i+1;
    return lv;
}

static int TotalAllocated(void)
{
    int t=0;
    for(int i=0; i<classCount; i++) t+=classes[i].allocatedXP;
    return t;
}

static int AvailXP(void) { return cls_totalXP - TotalAllocated(); }

// Auto-calculate cls_totalXP
void UpdateTotalXP(int level, int xp, int *tnl)
{
    cls_totalXP = xp;
    for(int i = 0; i < level; i++)
        cls_totalXP += tnl[i];
}

// Classes tab: Add-Class Modal
void DrawClassModal(void)
{
    DrawRectangle(0, 0, 900, 600, (Color){0, 0, 0, 155});

    Rectangle m = {(float)(900/2 - 242), (float)(600/2 - 218), 484.f, 436.f};
    Panel(m, C_PANEL, C_GOLD);

    DrawText("Add New Class", (int)m.x+22, (int)m.y+16, 22, C_GOLD_L);
    DrawLineEx((Vector2){m.x+22, m.y+52},(Vector2){m.x+m.width-22, m.y+52}, 1.f, C_BORDER);

    int px=(int)m.x+24, py=(int)m.y+64;

    DrawText("Class Name", px, py, 13, C_MUTED);
    py+=18;
    Rectangle nr={(float)px,(float)py,m.width-48.f,40.f};
    TBoxTick(&tbNewName, nr);
    TBoxDraw(&tbNewName, nr, "e.g.  Warrior,  Mage,  Ranger ...");
    py+=56;

    char capLabel[32]; snprintf(capLabel,sizeof(capLabel),"Level Cap  —  %d",newCap);
    DrawText(capLabel, px, py, 13, C_MUTED);
    py+=20;

    float t=(newCap-5)/15.f;
    Rectangle track={(float)px,(float)(py+8),m.width-48.f,6.f};
    DrawRectangleRounded(track, 0.5f, 8, C_BORDER);
    if(t>0.f){ Rectangle fill={track.x,track.y,t*track.width,track.height}; DrawRectangleRounded(fill,0.5f,8,C_GOLD); }
    float kx=track.x+t*track.width;
    DrawCircle((int)kx,(int)(track.y+3.f),11,C_PANEL3);
    DrawCircle((int)kx,(int)(track.y+3.f), 9,C_GOLD_L);

    if(IsMouseButtonDown(MOUSE_LEFT_BUTTON)){
        Vector2 mp=GetMousePosition();
        if(mp.y>=track.y-14.f&&mp.y<=track.y+26.f&&mp.x>=track.x-12.f&&mp.x<=track.x+track.width+12.f){
            float nt=(mp.x-track.x)/track.width;
            nt=fmaxf(0.f,fminf(1.f,nt));
            newCap=5+(int)roundf(nt*15.f);
        }
    }
    DrawText("5",  px,                    py+24, 12, C_MUTED);
    DrawText("20", (int)(m.x+m.width-36), py+24, 12, C_MUTED);
    py+=56;

    DrawText("A .txt file is created automatically. Open it in any", px, py, 13, C_MUTED); py+=18;
    DrawText("text editor, fill in XP values, then click Reload.",   px, py, 13, C_MUTED); py+=46;

    Rectangle cancelR={(float)px,                  (float)py,200.f,42.f};
    Rectangle addR   ={m.x+m.width-224.f,(float)py,200.f,42.f};

    if(Btn(cancelR,"Cancel",C_PANEL3,C_TEXT)){
        showModal=false;
        memset(tbNewName.buf,0,sizeof(tbNewName.buf));
    }
    if(Btn(addR,"Add Class + Create File",C_GOLD,C_BG)){
        if(strlen(tbNewName.buf)>0 && classCount<MAX_CLASSES){
            Class *c=&classes[classCount++];
            memset(c,0,sizeof(*c));
            for(int j=0;j<MAX_CLASS_LEVELS;j++) c->levelReqs[j]=-1;
            strncpy(c->name,tbNewName.buf,MAX_CLASS_NAME-1);
            c->levelCap=newCap; c->allocatedXP=0;
            CreateClassFile(c); SaveClassState();
            char fn[256]; ClassFname(c,fn,sizeof(fn));
            ShowNotif(TextFormat("'%s' added! Edit %s and click Reload.",c->name,fn));
            showModal=false;
            memset(tbNewName.buf,0,sizeof(tbNewName.buf));
            newCap=10;
        } else ShowNotif("Please enter a class name first.");
    }
}

void CancelClassModal(void)
{
    showModal=false;
    memset(tbNewName.buf,0,sizeof(tbNewName.buf));
}

// Classes tab: right-side detail panel
static void DrawClassDetail(int x, int y, int w, int h)
{
    if(selectedCls<0||selectedCls>=classCount){
        const char *hint="<-- Select a class or add a new one.";
        DrawText(hint, x+(w-MeasureText(hint,14))/2, y+h/2-8, 14, C_MUTED);
        return;
    }

    Class *c  = &classes[selectedCls];
    int    lv = GetLevel(c);
    int    av = AvailXP();

    if(CheckCollisionPointRec(GetMousePosition(),(Rectangle){x,y,w,h}))
        detailScroll -= GetMouseWheelMove()*52.f;
    if(detailScroll<0.f) detailScroll=0.f;

    BeginScissorMode(x, y, w, h);

    int px=x+22, pw=w-44;
    int py=y+18-(int)detailScroll;

    int nw=MeasureText(c->name,28);
    DrawText(c->name, px, py, 28, C_GOLD_L);
    char lvs[32]; snprintf(lvs,sizeof(lvs),"Lv %d / %d",lv,c->levelCap);
    ClsBadge(px+nw+14, py+6, lvs, lv==c->levelCap?C_GREEN:C_PANEL3, lv==c->levelCap?C_GREEN_L:C_MUTED);
    if(lv==c->levelCap)
        ClsBadge(px+nw+14+MeasureText(lvs,13)+36, py+6, "MAX LEVEL", C_GREEN, C_GREEN_L);
    py+=48;

    DrawText(TextFormat("Allocated XP:  %d", c->allocatedXP), px, py, 16, C_TEXT);
    py+=26;
    ProgBar((Rectangle){(float)px,(float)py,(float)pw,8}, c->levelCap>0?(float)lv/(float)c->levelCap:0.f, C_GOLD);
    py+=22;

    Panel((Rectangle){(float)px,(float)py,(float)pw,100.f}, C_PANEL2, C_BORDER);
    DrawText("Distribute XP", px+14, py+11, 14, C_MUTED);

    Rectangle ir={(float)(px+14),(float)(py+34),172.f,38.f};
    TBoxTick(&tbDistXP, ir);
    TBoxDraw(&tbDistXP, ir, "Amount...");

    Rectangle addB={(float)(px+pw-184),(float)(py+34),88.f,38.f};
    Rectangle subB={(float)(px+pw- 90),(float)(py+34),80.f,38.f};

    if(Btn(addB,"+ Add",C_GOLD,C_BG)){
        int amt=atoi(tbDistXP.buf);
        if(amt>0){ int add=amt>av?av:amt; c->allocatedXP+=add; SaveClassState();
            ShowNotif(TextFormat("Added %d XP to %s.",add,c->name)); }
    }
    if(Btn(subB,"- Sub",C_PANEL3,C_TEXT)){
        int amt=atoi(tbDistXP.buf);
        if(amt>0){ c->allocatedXP-=amt; if(c->allocatedXP<0) c->allocatedXP=0;
            SaveClassState(); ShowNotif(TextFormat("Removed %d XP from %s.",amt,c->name)); }
    }
    py+=116;

    DrawText("Level Requirements", px, py, 15, C_TEXT);

    if(SmallBtn((Rectangle){(float)(px+pw-142),(float)(py-2),136.f,26.f},"Reload from file",C_PANEL3,C_MUTED)){
        for(int i=0;i<MAX_CLASS_LEVELS;i++) c->levelReqs[i]=-1;
        LoadClassFile(c);
        ShowNotif(TextFormat("Reloaded requirements for %s.",c->name));
    }
    py+=34;

    int cols=4, cw=pw/cols, ch=64;                                              // CHANGED: cols 5->4, ch 58->64
    for(int i=0; i<c->levelCap; i++){
        int col=i%cols, row=i/cols;
        Rectangle cell={(float)(px+col*cw),(float)(py+row*ch),(float)(cw-6),(float)(ch-6)};
        bool reached=(c->levelReqs[i]>=0&&c->levelReqs[i]<=c->allocatedXP);
        bool cur=(i+1==lv);

        Color cbg=(reached||cur)?(Color){26,48,24,255}:C_PANEL2;
        Color cbd=(reached||cur)?C_GREEN:C_BORDER;
        DrawRectangleRounded(cell,0.10f,8,cbg);
        DrawRectangleRoundedLinesEx(cell,0.10f,8,1.5f,cbd);

        char ll[16]; snprintf(ll,sizeof(ll),"Lv %d",i+1);
        DrawText(ll,(int)(cell.x+8),(int)(cell.y+6),12,C_MUTED);

        if(c->levelReqs[i]>=0){
            char rs[24]; snprintf(rs,sizeof(rs),"%d XP",c->levelReqs[i]);
            DrawText(rs,(int)(cell.x+8),(int)(cell.y+24),14,C_TEXT);
        } else DrawText("— XP",(int)(cell.x+8),(int)(cell.y+24),14,C_MUTED);
    }
    int rows=(c->levelCap+cols-1)/cols;
    py+=rows*ch+24;

    if(Btn((Rectangle){(float)(px+pw-160),(float)py,152.f,38.f},"Delete Class",C_RED,C_TEXT)){
        for(int i=selectedCls;i<classCount-1;i++) classes[i]=classes[i+1];
        classCount--; selectedCls=-1; detailScroll=0.f;
        SaveClassState(); ShowNotif("Class deleted.");
    }

    int virtualBottom=py+(int)detailScroll+60;
    float maxS=fmaxf(0.f,(float)(virtualBottom-(y+h)));
    if(detailScroll>maxS) detailScroll=maxS;

    EndScissorMode();
}

// Classes tab: left-side sidebar
static void DrawClassSidebar(int x, int y, int w, int h)
{
    DrawRectangle(x, y, w, h, C_PANEL);
    DrawLine(x+w-1, y, x+w-1, y+h, C_BORDER);

    int px=x, py=y, pw=w-28;

    // XP Summary Card
    Panel((Rectangle){(float)px,(float)py,(float)pw,118.f}, C_PANEL2, C_BORDER);
    DrawText("TOTAL XP",  px+12, py+10, 11, C_MUTED);
    DrawText(TextFormat("%d", cls_totalXP), px+12, py+26, 26, C_GOLD_L);
    DrawLine(px+12, py+62, px+pw-12, py+62, C_BORDER);
    DrawText("AVAILABLE", px+12, py+70, 11, C_MUTED);
    int av=AvailXP();
    DrawText(TextFormat("%d",av), px+12, py+86, 22, av>0?C_GREEN:C_RED);
    py+=132;

    // Add class button
    if(Btn((Rectangle){(float)px,(float)py,(float)pw,40.f},"+ Add New Class",C_GOLD,C_BG))
        showModal=true;
    py+=48;

    DrawText(TextFormat("CLASSES  (%d)",classCount), px, py, 11, C_MUTED);
    py+=13;

    // Scrollable class list
    int listH=h-(py-y)-10;
    int itemH=62;

    if(CheckCollisionPointRec(GetMousePosition(),(Rectangle){(float)x,(float)py,(float)w,(float)listH})){
        sideScroll -= GetMouseWheelMove()*60.f;
        float maxS=fmaxf(0.f,(float)(classCount*itemH-listH));
        if(sideScroll<0.f) sideScroll=0.f;
        if(sideScroll>maxS) sideScroll=maxS;
    }

    BeginScissorMode(x, py, w, listH);
    int ly=py-(int)sideScroll;

    for(int i=0; i<classCount; i++){
        Class *c=&classes[i];
        int lv=GetLevel(c);
        bool sel=(i==selectedCls);

        Rectangle ir={(float)(px+2),(float)ly,(float)(pw-2),(float)(itemH-6)};
        bool hov=CheckCollisionPointRec(GetMousePosition(),ir);
        Color bg=sel?C_PANEL3:hov?C_PANEL2:C_PANEL;
        Color bd=sel?C_GOLD:C_BORDER;

        DrawRectangleRounded(ir,0.08f,8,bg);
        DrawRectangleRoundedLinesEx(ir,0.08f,8,1.5f,bd);
        DrawText(c->name,(int)(ir.x+10),(int)(ir.y+7),16,sel?C_GOLD_L:C_TEXT);

        char lb[28]; snprintf(lb,sizeof(lb),"Lv %d/%d",lv,c->levelCap);
        ClsBadge((int)(ir.x+10),(int)(ir.y+30),lb,
                 lv==c->levelCap?C_GREEN:C_PANEL3, lv==c->levelCap?C_GREEN_L:C_MUTED);

        if(hov&&IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
            selectedCls=i; detailScroll=0.f;
            memset(tbDistXP.buf,0,sizeof(tbDistXP.buf));
        }
        ly+=itemH;
    }
    EndScissorMode();
}

// Classes tab entry point
void DrawTabClasses(int cX, int cY)
{
    int sideW   = 200;
    int h       = 572 - cY;
    int detailX = cX + sideW;
    int detailW = 900 - detailX;

    DrawClassSidebar(cX, cY, sideW, h);
    DrawClassDetail (detailX, cY, detailW, h);
}
