use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use ssd1306::{ prelude::*, I2CDisplayInterface};
use esp_idf_hal::prelude::Peripherals;

use esp_idf_hal::units::*;
// use esp_idf_hal::gpio;
use esp_idf_hal::i2c::I2cDriver;
use esp_idf_hal::i2c;
use esp_idf_hal::adc;
use esp_idf_hal::gpio;

use std::sync::mpsc;
use std::thread;
use std::time::Duration;


// use std::fmt::Write;

mod display;

let const high_set_point = 170;
let const low_set_point = 100;



fn main() {
    esp_idf_sys::link_patches();
    println!("Hello, world!");
    #[allow(unused)]
    let peripherals = Peripherals::take().unwrap();
    let pins = peripherals.pins;
    let mut adc1 = peripherals.adc1;
    

    let sda = pins.gpio5;
    let scl = pins.gpio4;

    let relay = pins.gpio3;

    let i2c = peripherals.i2c0;
    let thermistor_pin = pins.gpio2;
    let mut relay = gpio::PinDriver::output(relay).unwrap();
    relay.set_high();
    // set up relay output


    

    let interface: I2CInterface<I2cDriver> = I2CDisplayInterface::new(i2c::I2cDriver::new(
        i2c,
        sda,
        scl,
        &i2c::I2cConfig::new().baudrate(400.kHz().into()),
    ).unwrap());   
  
    let (display_message, rx) = mpsc::channel::<display::display_data>();
    // thread::sleep(Duration::from_secs(1));
    let displayThread = thread::spawn( move || display::graphicWrite(interface, &rx));

    // display_message.send("Hello Text".to_owned()).unwrap();
    // // graphicWrite(interface);

    // console_write(interface);

    // displayThread.join();  //wait for display thread to finish befor continuing

    let temp_thread = thread::spawn( move || temps::monitor_temps(&mut adc1, thermistor_pin, &mut relay, &display_message));

    println!("Main Finished");
}




mod temps{
    
    use esp_idf_hal::adc;
    use esp_idf_hal::adc::ADC1;
    use esp_idf_hal::gpio::Gpio2;
    use esp_idf_hal::gpio::Gpio3;
    use std::thread;
    use std::sync::mpsc;
    use std::time::Duration;
    use esp_idf_hal::gpio;

    use crate::display;

    pub fn monitor_temps(adc1: &mut ADC1,Thermistor_pin: Gpio2, relay: &mut gpio::PinDriver<Gpio3, gpio::Output>, display: &mpsc::Sender<display::display_data>){

        let mut ad1_ch0 = adc::AdcDriver::new(
            adc1,
            &adc::config::Config::new(),
        ).unwrap();

        let min_temp = -24;
        let max_temp = 80;
        let min_count = 2327;
        let max_count = 282;

        let slope = (min_count - max_count)/(min_temp - max_temp);
        let b = max_temp -max_count*slope;
        let BETA = 1712.;
        let ADCMAX = 2500.;

        let mut thermistor = adc::AdcChannelDriver::<_, adc::Atten11dB<adc::ADC1>>::new(Thermistor_pin).unwrap();
    
            loop{
                match ad1_ch0.read(&mut thermistor){
                    Ok(x) => {  
                                let adc_count = x as f64; 
                                println!("count: {x}\n");
                                let temp_c = (1.0/
                                    ((1.0/(ADCMAX/adc_count - 1.0)).log10() / BETA
                                    + 1.0 / 298.15)
                                    -273.15);
                                let temp_f = ((temp_c * 1.8 + 32.0)*10.).round()/10.;
                                    if temp_f <140.0
                                        {relay.set_high();}
                                    else if temp_f > 150.0
                                        {relay.set_low();}
                                let data = display::display_data { temp: temp_f.to_string(), status :"test".to_owned()};
                                display.send(data);
                            },
                    Err(e) => println!("Error Reading ADC: {e}\n"),
                }

                thread::sleep(Duration::from_secs(1));
            }
    }
}
NOCOMNCVCCGNDINLED1PWRRelay Module
4-Digit Display