#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <stdio.h>

#define ZIP_URL "https://github.com/StitcyYT/Complex-X-/archive/refs/heads/main.zip"

#define ID_TEXTSTATUS 101
#define ID_PROGRESS   102

static HWND hStatusText = NULL;
static HWND hProgressBar = NULL;

DWORD WINAPI InstallThread(LPVOID lpParam)
{
    (void)lpParam;
    char temp[512], zipPath[512], extractDir[512];
    char exeSrc[512], desk[512], dest[512];
    char cmd[1024];
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;

    SetWindowTextA(hStatusText, "Downloading Complexx Raycaster...");
    SendMessage(hProgressBar, PBM_SETMARQUEE, TRUE, 0);

    GetTempPathA(sizeof(temp), temp);
    snprintf(zipPath, sizeof(zipPath), "%s\\complexx_repo.zip", temp);
    snprintf(extractDir, sizeof(extractDir), "%s\\complexx_extract", temp);

    if (FAILED(URLDownloadToFileA(NULL, ZIP_URL, zipPath, 0, NULL)))
    {
        MessageBoxA(NULL, "Download failed. Please check your internet connection.", "Complexx Installer", MB_ICONERROR);
        PostQuitMessage(1);
        return 1;
    }

    SetWindowTextA(hStatusText, "Extracting game files...");
    CreateDirectoryA(extractDir, NULL);

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;

    snprintf(cmd, sizeof(cmd), "tar -xf \"%s\" -C \"%s\"", zipPath, extractDir);
    if (!CreateProcessA(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
    {
        DeleteFileA(zipPath);
        MessageBoxA(NULL, "Extraction process failed to start.", "Complexx Installer", MB_ICONERROR);
        PostQuitMessage(1);
        return 1;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    DeleteFileA(zipPath);

    SetWindowTextA(hStatusText, "Creating Desktop shortcut...");
    SHGetFolderPathA(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, desk);

    snprintf(exeSrc, sizeof(exeSrc), "%s\\Complex-X--main\\build\\raycaster.exe", extractDir);
    snprintf(dest, sizeof(dest), "%s\\Complexx Raycaster.exe", desk);

    if (!CopyFileA(exeSrc, dest, FALSE))
    {
        char err[256];
        snprintf(err, sizeof(err), "Setup installation failed (error %lu)", GetLastError());
        MessageBoxA(NULL, err, "Complexx Installer", MB_ICONERROR);
        PostQuitMessage(1);
        return 1;
    }

    snprintf(cmd, sizeof(cmd), "rmdir /s /q \"%s\"", extractDir);
    CreateProcessA(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    MessageBoxA(NULL, "Complexx Raycaster is ready! Enjoy your game.", "Complexx Installer", MB_ICONINFORMATION);
    PostQuitMessage(0);
    return 0;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_CREATE:
        {
            INITCOMMONCONTROLSEX icex;
            icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
            icex.dwICC = ICC_PROGRESS_CLASS;
            InitCommonControlsEx(&icex);

            hStatusText = CreateWindowExA(0, "STATIC", "Initializing setup...", 
                WS_CHILD | WS_VISIBLE | SS_CENTER, 
                20, 30, 360, 25, hwnd, (HMENU)ID_TEXTSTATUS, NULL, NULL);

            hProgressBar = CreateWindowExA(0, PROGRESS_CLASSA, NULL, 
                WS_CHILD | WS_VISIBLE | PBS_MARQUEE, 
                20, 70, 360, 25, hwnd, (HMENU)ID_PROGRESS, NULL, NULL);

            CreateThread(NULL, 0, InstallThread, NULL, 0, NULL);
            break;
        }
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProcA(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    (void)hPrevInstance;
    (void)lpCmdLine;

    WNDCLASSEXA wc = {0};
    wc.cbSize = sizeof(WNDCLASSEXA);
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = "ComplexxInstallerClass";

    if (!RegisterClassExA(&wc)) return 1;

    HWND hwnd = CreateWindowExA(
        WS_EX_DLGMODALFRAME,
        "ComplexxInstallerClass",
        "Complexx Raycaster Setup",
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, 415, 160,
        NULL, NULL, hInstance, NULL
    );

    if (!hwnd) return 1;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    MSG msg;
    while (GetMessageA(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessageA(&msg);
    }

    return (int)msg.wParam;
}