//! # MQTT
// Use http://www.hivemq.com/demos/websocket-client/
// Topics to subscribe:
//    - <uuid>/hello
//    - <uuid>/color_topic
//    - <uuid>/sensor_data/temperature
//    - <uuid>/sensor_data/temperature
// tests
use bsc::{
    led::{RGB8, WS2812RMT},
    wifi::wifi,
};
use embedded_svc::mqtt::client::{
    Client,
    Details::{Complete, InitialChunk, SubsequentChunk},
    Event::{self, Received},
    Message, Publish, QoS,
};
use esp32_s3_dkc02_bsc as bsc;
use esp_idf_svc::{
    log::EspLogger,
    mqtt::client::{EspMqttClient, EspMqttMessage, MqttClientConfiguration},
};
use shtcx::{self, PowerMode};
use std::{borrow::Cow, convert::TryFrom, thread::sleep, time::Duration};
// If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use esp_idf_hal::{
    delay::FreeRtos,
    i2c::{config::MasterConfig, Master, MasterPins, I2C0},
    peripherals::Peripherals,
    prelude::*,
};
use esp_idf_sys as _;
use log::{error, info};

// imported message topics
use mqtt_messages::{cmd_topic_fragment, hello_topic, Command, RawCommandData};

const UUID: &'static str = get_uuid::uuid();

#[toml_cfg::toml_config]
pub struct Config {
    #[default("broker.mqttdashboard.com")]
    mqtt_host: &'static str,
    #[default("")]
    mqtt_user: &'static str,
    #[default("")]
    mqtt_pass: &'static str,
    #[default("Wokwi-GUEST")]
    wifi_ssid: &'static str,
    #[default("")]
    wifi_psk: &'static str,
}

fn main() -> anyhow::Result<()> {
    // Setup
    esp_idf_sys::link_patches();

    EspLogger::initialize_default();

    let app_config = CONFIG;
    println!("Test");
    info!("our UUID is:");
    info!("{}", UUID);
    let peripherals = Peripherals::take().unwrap();

    let sda = peripherals.pins.gpio1;
    let scl = peripherals.pins.gpio2;

    let i2c = Master::<I2C0, _, _>::new(
        peripherals.i2c0,
        MasterPins { sda, scl },
        <MasterConfig as Default>::default().baudrate(400.kHz().into()),
    )?;

    // Create an instance of the SHTC3 sensor.
    let mut sht = shtcx::shtc3(i2c);

    let mut led = WS2812RMT::new()?;
    led.set_pixel(RGB8::new(1, 1, 0))?;

    let _wifi = wifi(app_config.wifi_ssid, app_config.wifi_psk)?;

    // Client configuration:
    let broker_url = if app_config.mqtt_user != "" {
        format!(
            "mqtt://{}:{}@{}",
            app_config.mqtt_user, app_config.mqtt_pass, app_config.mqtt_host
        )
    } else {
        format!("mqtt://{}", app_config.mqtt_host)
    };

    let mqtt_config = MqttClientConfiguration::default();

    // Your Code:

    // 1. Create a client with default configuration and empty handler
    let mut client = EspMqttClient::new(broker_url, &mqtt_config, move |message_event| {
        // ... your handler code here - leave this empty for now
        // we'll add functionality later in this chapter
    })?;

    // 2. publish an empty hello message
    let payload: &[u8] = &[];
    client.publish(&hello_topic(UUID), QoS::AtLeastOnce, true, payload)?;

    loop {
        sht.start_measurement(PowerMode::NormalMode).unwrap();
        sleep(Duration::from_secs(1));
        let meaurement = sht.get_measurement_result().unwrap();
        let temp = meaurement.temperature.as_degrees_celsius();
        // 3. publish CPU temperature
        client.publish(
            &mqtt_messages::temperature_data_topic(UUID),
            QoS::AtLeastOnce,
            false,
            &temp.to_be_bytes() as &[u8],
        )?;
    }
}
SHTC3Breakout