// Test runner for designer UI tests
#pragma once

#include "window_controller.h"
#include "log_parser.h"
#include "hierarchy_reader.h"
#include <string>
#include <vector>
#include <functional>
#include <filesystem>
#include <nlohmann/json.hpp>

namespace mosis::test {

// Test result status
enum class TestStatus {
    Passed,
    Failed,
    Skipped,
    Error
};

// Individual test result
struct TestResult {
    std::string name;
    TestStatus status;
    std::string message;
    double durationMs;

    nlohmann::json ToJson() const;
};

// Test suite result
struct TestSuiteResult {
    std::string name;
    std::vector<TestResult> tests;
    int passed = 0;
    int failed = 0;
    int skipped = 0;
    int errors = 0;
    double totalDurationMs = 0;

    nlohmann::json ToJson() const;
    void SaveToFile(const std::filesystem::path& path) const;
};

// Test context passed to each test
struct TestContext {
    WindowController& window;
    LogParser& log;
    HierarchyReader& hierarchy;
};

// Test function signature
using TestFunc = std::function<bool(TestContext&)>;

// Individual test case
struct TestCase {
    std::string name;
    TestFunc func;
};

// App icon positions for tests
struct AppPosition {
    int x;
    int y;
};

// Predefined positions on phone screen (540x960)
namespace AppPositions {
    // Navigation buttons (in app-bar, 56px high starting after 24px status bar)
    // Status bar: y=0-24, App bar: y=24-80, back button at left with 16px padding
    // Use y=40 which is in app-bar on screens with app-bar, but in padding on home
    constexpr AppPosition BackButton = {40, 40};  // In app-bar zone, safe on home screen

    // App grid positions - Row 1 (starting around y=100 after app-bar)
    constexpr AppPosition Phone = {67, 120};
    constexpr AppPosition Messages = {202, 120};
    constexpr AppPosition Contacts = {337, 120};
    constexpr AppPosition Browser = {472, 120};
    // Row 2
    constexpr AppPosition Gallery = {67, 220};
    constexpr AppPosition Camera = {202, 220};
    constexpr AppPosition Settings = {337, 220};
    constexpr AppPosition Music = {472, 220};

    // Dock positions - 80px tall at bottom, items centered at y = height - 40
    // 4 items with space-around in 540px - 64px padding = 476px content
    // Each item 56px, total 224px, remaining 252px = ~63px per item spacing
    // Item centers: ~92, ~211, ~330, ~449
    // Note: Using 920 for Y (phone space), will be scaled by window size
    // Adjusted first item X slightly right due to hit testing issues
    constexpr AppPosition DockPhone = {100, 920};
    constexpr AppPosition DockMessages = {211, 920};
    constexpr AppPosition DockContacts = {330, 920};
    constexpr AppPosition DockBrowser = {449, 920};
}

class TestRunner {
public:
    TestRunner();
    ~TestRunner();

    // Configuration
    void SetDesignerPath(const std::filesystem::path& path);
    void SetDocumentPath(const std::filesystem::path& path);
    void SetLogPath(const std::filesystem::path& path);
    void SetHierarchyPath(const std::filesystem::path& path);
    void SetStartupTimeoutMs(int ms) { m_startupTimeoutMs = ms; }
    void SetActionDelayMs(int ms) { m_actionDelayMs = ms; }

    // Add test cases
    void AddTest(const std::string& name, TestFunc func);

    // Run all tests
    TestSuiteResult RunAll();

    // Run a specific test by name
    TestResult RunTest(const std::string& name);

    // Start/stop designer
    bool StartDesigner();
    void StopDesigner();

    // Get components for manual testing
    WindowController& GetWindow() { return m_window; }
    LogParser& GetLog() { return m_log; }
    HierarchyReader& GetHierarchy() { return m_hierarchy; }

private:
    TestResult ExecuteTest(const TestCase& test);

    std::filesystem::path m_designerPath;
    std::filesystem::path m_documentPath;
    std::filesystem::path m_logPath;
    std::filesystem::path m_hierarchyPath;

    int m_startupTimeoutMs = 15000;
    int m_actionDelayMs = 500;

    std::vector<TestCase> m_tests;
    WindowController m_window;
    LogParser m_log;
    HierarchyReader m_hierarchy;

    HANDLE m_designerProcess = nullptr;
};

} // namespace mosis::test
