#include "gamecube.h"
#include <algorithm>
#include <ctime>
#include <iostream>
//enum game
//Ab Zeile 114 if game won
//Ab Zeile 148 checking match?


// -----------------------------------------------------------
// Initialisierung
// -----------------------------------------------------------

void innitGame(int pairCount,
                std::vector<gamecube> &cubes,
                std::vector<Vec3> &positions )
{
    cubes.clear();
    positions.clear();

    // Spielfeld grob quadratisch machen
    int total = pairCount * 2;
    int cols = ceil(sqrt(total));
    int rows = (total + cols - 1) / cols;

    float spacing = 2.2f;

    // Dynamische Positionen erzeugen
    for (int r = 0; r < rows; r++)
    {
        for (int c = 0; c < cols; c++)
        {
            if ((int)positions.size() < total)
            {
                positions.push_back({
                    (c - cols/2.0f) * spacing,
                    0,
                    (r - rows/2.0f) * spacing
                });
            }
        }
    }

    // Colors erzeugen
    std::vector<Color> colorPool;
    colorPool.reserve(total);

    for (int i = 0; i < pairCount; i++)
    {
        Color col = {
            (unsigned char)(rand() % 256),
            (unsigned char)(rand() % 256),
            (unsigned char)(rand() % 256),
            255
        };

        colorPool.push_back(col);
        colorPool.push_back(col); // Paar
    }

    // Shuffle
    for (int i = total - 1; i > 0; --i)
        std::swap(colorPool[i], colorPool[rand() % (i + 1)]);

    // Würfel erstellen
    for (int i = 0; i < total; i++)
        cubes.emplace_back(positions[i], colorPool[i]);


}
// -----------------------------------------------------------
// 3D Memory Game – Hauptprogramm
// -----------------------------------------------------------
int main()
{
    //NEU Counter
    int counter = 0;


    // Zufall initialisieren
    srand(time(NULL));

    // Fenster und Kamera
    InitWindow(800, 600, "3D Memory Game with Matrix3D Library");
    SetTargetFPS(60);

    Camera3D camera{};
    camera.position = {6.0f, 6.0f, 6.0f};
    camera.target   = {0.0f, 0.0f, 0.0f};
    camera.up       = {0.0f, 1.0f, 0.0f};
    camera.fovy     = 45.0f;
    camera.projection = CAMERA_PERSPECTIVE;

    // -------------------------------------------------------
    // Spielvariablen
    // -------------------------------------------------------
    // Nur 3 Farben für 3 Paare
    int pairCount = 2;    // <-- vorerst fixe Anzahl
    std::vector<Vec3> positions;
    std::vector<gamecube> cubes;

    innitGame(pairCount, cubes, positions);



    // Karten/Würfel erstellen

    gamecube* first  = nullptr;
    gamecube* second = nullptr;
    float flipSpeed = 5.0f;  // Drehgeschwindigkeit
    bool gameWon = false;

    GameState state = GameState::Idle; //legen wir fest, in welchem Zustand das Spiel startet

    // -----------------------------------------------------------
    // Hauptspielschleife
    // -----------------------------------------------------------

    while (!WindowShouldClose())
    {

        // Klick-Erkennung
        if (!gameWon
            && (state == GameState::Idle || state == GameState::OneFlipped)
            && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {

            // nur im Idle- oder OneFlipped-Zustand wird reagiert<-------------------------------------------------
                //Wenn einer Dreht, clicken blockieren
            // ...

            Vector2 mouse = GetMousePosition();

            for (auto &c : cubes)           //Hier die State Logik
            {
                std::cout<<("State missing");
                if (!c.IsFlipped() && !c.IsMatched())   //<--------------- Zustandwechsel anpassen
                {
                    Vector2 screenPos = GetWorldToScreen(
                        {c.GetPosition().x, c.GetPosition().y, c.GetPosition().z}, camera);

                    if (fabs(mouse.x - screenPos.x) < 40 &&
                        fabs(mouse.y - screenPos.y) < 40)
                    {
                        c.FlipForward(); //<-----Animation Start
                        //Neu Counter
                        counter++;

                        if (state == GameState::Idle)       //Neu (Ü4)
                            state = GameState::OneFlipped;
                        else
                            state = GameState::LockInput;

                        break; // 🔒 nur EIN Würfel pro Klick
                    }
                }
            }
        }

        // Animation aller Würfel
        for (auto &c : cubes)
        {
            c.Update(flipSpeed);

            // Sobald ein Würfel vollständig umgedreht ist → merken
            if (c.IsFlipped() && !c.IsMatched())
            {
                if (!first)
                    first = &c;
                else if (!second && &c != first)
                    second = &c;
            }
        }

        // Matching-Logik
        if (first && second)
        {
            //counter hier macht umdrehungen

            Color col1 = first->GetColor();
            Color col2 = second->GetColor();

            if (col1.r == col2.r &&
                col1.g == col2.g &&
                col1.b == col2.b)
            {
                first->SetMatched(true);
                second->SetMatched(true);
            }
            else
            {
                first->FlipBackward();
                second->FlipBackward();
            }


            first = second = nullptr;
            state = GameState::Idle; //neu
        }

        // -----------------------------
        // WIN CHECK
        // -----------------------------
        if (!gameWon)
            gameWon = std::all_of(cubes.begin(), cubes.end(), [](const gamecube &c){ return c.IsMatched(); });

        // -----------------------------------------------------------
        // Zeichnen
        // -----------------------------------------------------------
        BeginDrawing();
        ClearBackground(RAYWHITE);
        BeginMode3D(camera);

        for (auto &c : cubes)
            c.Draw();

        EndMode3D();
        if (gameWon)
            DrawText("Congrats! You found all pairs!", 150, 260, 30, DARKBLUE);
        else
            DrawText("Flip 2 cubes - find matching pairs!", 10, 10, 20, DARKGRAY);
            //Neu Counter
            DrawText(TextFormat("Counter: %i",counter/2),10,40,20,DARKGRAY);    //counter//2 da sonst doppelt

        EndDrawing();
    }

    CloseWindow();
    return 0;
}
