#define PYNECT_DIRECT_USE_DLL
#include "pynect_direct.h"
#include <iomanip>
#include <iostream>
#include <vector>
#include <string>

static void require(int code, const std::string& what)
{
    if (code != PYNECT_DIRECT_SUCCESS) {
        std::cerr << "[FAIL] " << what << ": return code = " << code << std::endl;
        throw std::runtime_error(what);
    }
}

int main()
{
    try {
        /* 1. 扫描设备 */
        int n = pynect_direct_scan_devices();
        if (n <= 0) {
            std::cout << "No device found." << std::endl;
            system("pause");
            return 1;
        }
        std::cout << "Found " << n << " device(s)." << std::endl;

        /* 2. 打开设备 */
        require(pynect_direct_open_device(0), "open_device");

        /* 3. 设备信息 */
        PynectDirectDeviceInfo info{};
        require(pynect_direct_get_device_info(&info), "get_device_info");
        std::cout << "Model:   " << info.model << std::endl
                  << "Serial:  " << info.serial_number << std::endl
                  << "Hardware:" << info.hardware_version << std::endl;

        /* 4. 数据点数 */
        uint16_t count = 0;
        require(pynect_direct_get_wavelength_count(&count), "get_wavelength_count");
        std::cout << "Wavelength count: " << count << std::endl;

        /* 5. 波长范围 */
        double start_nm = 0.0, end_nm = 0.0;
        require(pynect_direct_get_full_wavelength_range(&start_nm, &end_nm),
                "get_full_wavelength_range");
        std::cout << "Wavelength range: " << start_nm << " ~ " << end_nm << " nm" << std::endl;

        /* 6. 读取波长坐标 */
        std::vector<double> wavelengths(count);
        require(pynect_direct_get_full_wavelength_data(wavelengths.data(), count),
                "get_full_wavelength_data");

        /* 7. 设置积分时间并采集光谱 */
        pynect_direct_set_integration_time(50000);   /* 50 ms，临时设置 */
        std::vector<uint16_t> spectrum(count);
        require(pynect_direct_get_full_spectrum_data(spectrum.data(), count),
                "get_full_spectrum_data");

        /* 8. 两列打印：波长 + 对应强度（前 5 点 + 后 5 点） */
        std::cout << std::setw(6) << "Index" << std::setw(15) << "Wavelength(nm)"
                  << std::setw(11) << "Intensity" << std::endl;
        std::cout << std::setw(6) << "-----" << std::setw(15) << "--------------"
                  << std::setw(11) << "---------" << std::endl;
        for (int i = 0; i < 5; ++i)
            std::cout << std::setw(6) << i << std::setw(15) << std::fixed
                      << std::setprecision(3) << wavelengths[i]
                      << std::setw(11) << spectrum[i] << std::endl;
        if (count > 10)
            std::cout << "...  (total " << count << " points)" << std::endl;
        for (int i = count - 5; i < count; ++i)
            std::cout << std::setw(6) << i << std::setw(15) << std::fixed
                      << std::setprecision(3) << wavelengths[i]
                      << std::setw(11) << spectrum[i] << std::endl;

        /* 9. 指定波段（上位机截取） */
        if (start_nm < 400.0 && end_nm > 800.0) {
            require(pynect_direct_set_selected_wavelength_range(400.0, 800.0),
                    "set_selected_range");
            PynectDirectSelectedWavelengthRange sel{};
            require(pynect_direct_get_selected_wavelength_range(&sel),
                    "get_selected_range");
            std::cout << "Selected: pixels " << sel.start_pixel << ".."
                      << sel.end_pixel << ", count=" << sel.count << std::endl;
        }

        /* 10. 关闭设备 */
        pynect_direct_close_device();
        std::cout << "Done." << std::endl;
        system("pause");
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        system("pause");
        return 1;
    }
    return 0;
}
