#pragma once
#include <chrono>
#include <Eigen/Eigen>

#include "color.h"

using time_type     = decltype(std::chrono::high_resolution_clock::now());
using duration_type = decltype(std::chrono::high_resolution_clock::now() - std::chrono::high_resolution_clock::now());

inline time_type get_current_time() { return std::chrono::high_resolution_clock::now(); }

// 左上，右上，左下，右下
template<typename T>
struct rect_quad : std::array<T, 4> {
	// 默认构造函数由具体类型特化提供

	rect_quad() : std::array<T, 4>() {
	}

	// 单值构造
	rect_quad(const T& value) : std::array<T, 4>{ value, value, value, value } {
	}

	// 左右构造
	rect_quad(const T& left, const T& right) : std::array<T, 4>{ left, right, left, right } {
	}

	// 完整构造
	rect_quad(const T& left_top,    const T& right_top,
	          const T& left_bottom, const T& right_bottom) : std::array<T, 4>{
		left_top,
		right_top,
		left_bottom,
		right_bottom
	} {
	}
};

struct mirage_vertex_param_t {
    // 默认构造函数
    mirage_vertex_param_t() = default;

    // 通用构造函数 - 处理任何支持[]运算符的容器类型
    template<typename Container,
             typename = std::enable_if_t<
                !std::is_same_v<std::decay_t<Container>, mirage_vertex_param_t> &&
                !std::is_arithmetic_v<std::decay_t<Container>>
             >,
             typename = decltype(std::declval<Container>()[0])> // 检查是否支持索引访问
    mirage_vertex_param_t(const Container& container) {
        try {
            x = static_cast<float>(container[0]);

            // 对于各种不同类型的容器，尝试安全地获取剩余元素
            // 固定大小容器 (std::array, rect_quad 等)
            if constexpr (has_tuple_size<Container>::value) {
                constexpr size_t N = std::tuple_size<std::decay_t<Container>>::value;
                y = (N > 1) ? static_cast<float>(container[1]) : 0.0f;
                z = (N > 2) ? static_cast<float>(container[2]) : 0.0f;
                w = (N > 3) ? static_cast<float>(container[3]) : 0.0f;
            }
            // Eigen::Vector
            else if constexpr (is_eigen_vector<Container>::value) {
                constexpr int N = Container::RowsAtCompileTime;
                y = (N > 1) ? static_cast<float>(container[1]) : 0.0f;
                z = (N > 2) ? static_cast<float>(container[2]) : 0.0f;
                w = (N > 3) ? static_cast<float>(container[3]) : 0.0f;
            }
            // 动态大小容器 (std::vector 等)
            else if constexpr (has_size_method<Container>::value) {
	            y = (container.size() > 1) ? static_cast<float>(container[1]) : 0.0f;
                z = (container.size() > 2) ? static_cast<float>(container[2]) : 0.0f;
                w = (container.size() > 3) ? static_cast<float>(container[3]) : 0.0f;
            }
            // 其他情况 - 尝试访问但可能会抛出异常
            else {
                try { y = static_cast<float>(container[1]); } catch(...) { y = 0.0f; }
                try { z = static_cast<float>(container[2]); } catch(...) { z = 0.0f; }
                try { w = static_cast<float>(container[3]); } catch(...) { w = 0.0f; }
            }
        } catch(...) {
            // 如果第一个元素访问失败，设置所有值为0
            x = y = z = w = 0.0f;
        }
    }

    // 处理标量类型的构造函数
    template<typename T,
             typename = std::enable_if_t<std::is_arithmetic_v<std::decay_t<T>>>>
    mirage_vertex_param_t(T val) : x(val), y(0), z(0), w(0) {}

    // 处理2个标量的构造函数
    template<typename T>
    mirage_vertex_param_t(T x_val, T y_val) : x(x_val), y(y_val), z(0), w(0) {}

    // 处理3个标量的构造函数
    template<typename T>
    mirage_vertex_param_t(T x_val, T y_val, T z_val) : x(x_val), y(y_val), z(z_val), w(0) {}

    // 处理4个标量的构造函数
    template<typename T>
    mirage_vertex_param_t(T x_val, T y_val, T z_val, T w_val) :
        x(x_val), y(y_val), z(z_val), w(w_val) {}

    // 处理两个容器的构造函数
    template<typename A, typename B,
             typename = decltype(std::declval<A>()[0]),
             typename = decltype(std::declval<B>()[0])>
    mirage_vertex_param_t(const A& a, const B& b) :
        x(static_cast<float>(a[0])),
        y(static_cast<float>(a[1])),
        z(static_cast<float>(b[0])),
        w(static_cast<float>(b[1])) {}

    // 辅助类型特征检测
    template<typename T, typename = void>
    struct has_tuple_size : std::false_type {};

    template<typename T>
    struct has_tuple_size<T, std::void_t<decltype(std::tuple_size<std::decay_t<T>>::value)>>
        : std::true_type {};

    template<typename T, typename = void>
    struct has_size_method : std::false_type {};

    template<typename T>
    struct has_size_method<T, std::void_t<decltype(std::declval<T>().size())>>
        : std::true_type {};

    template<typename T, typename = void>
    struct is_eigen_vector : std::false_type {};

    template<typename T>
    struct is_eigen_vector<T, std::void_t<decltype(T::RowsAtCompileTime)>>
        : std::true_type {};

    // 数据成员
    union { float a; float x; };
    union { float b; float y; };
    union { float c; float z; };
    union { float d; float w; };
};


struct mirage_vertex_t {
	Eigen::Vector2f       position;
	Eigen::Vector2f       uv;
	linear_color          color;
	mirage_vertex_param_t param_a;
	mirage_vertex_param_t param_b;
	mirage_vertex_param_t param_c;
};

struct mirage_triangle_t {
	uint32_t indices[3];
};
