mod main_takt;
mod common;

use std::io::{self, Write};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use serialport::{self, SerialPort};
use std::time::Duration;

fn show_menu() {
    println!("\n=== 📋 Меню команд ===");
    println!("1. Отправить текстовое сообщение");
    println!("2. Отправить HEX данные");
    println!("3. Отправить HEX данные с CRC16");
    println!("4. Настройки порта");
    println!("5. Очистить экран");
    println!("6. Выход");
    print!("\nВыберите действие (1-6): ");
    io::stdout().flush().unwrap();
}

fn show_port_settings_menu() {
    println!("\n=== 📋 Настройки порта ===");
    println!("1. Скорость передачи (бод)");
    println!("2. Биты данных");
    println!("3. Стоп-биты");
    println!("4. Четность");
    println!("5. Управление потоком");
    println!("6. Вернуться в главное меню");
    print!("\nВыберите настройку (1-6): ");
    io::stdout().flush().unwrap();
}

fn configure_port_settings(port: &mut Box<dyn SerialPort>) {
    loop {
        show_port_settings_menu();
        let mut input = String::new();
        if io::stdin().read_line(&mut input).is_err() {
            continue;
        }

        match input.trim() {
            "1" => {
                print!("Введите скорость передачи (бод): ");
                io::stdout().flush().unwrap();
                let mut baud_input = String::new();
                if io::stdin().read_line(&mut baud_input).is_ok() {
                    if let Ok(baud) = baud_input.trim().parse::<u32>() {
                        if let Err(e) = port.set_baud_rate(baud) {
                            println!("❌ Ошибка установки скорости: {}", e);
                        } else {
                            println!("✅ Скорость установлена: {} бод", baud);
                        }
                    } else {
                        println!("❌ Ошибка: введите корректное число");
                    }
                }
            }
            "2" => {
                println!("\nВыберите количество бит данных:");
                println!("1. 5 бит");
                println!("2. 6 бит");
                println!("3. 7 бит");
                println!("4. 8 бит");
                print!("\nВыберите (1-4): ");
                io::stdout().flush().unwrap();
                let mut bits_input = String::new();
                if io::stdin().read_line(&mut bits_input).is_ok() {
                    let data_bits = match bits_input.trim() {
                        "1" => serialport::DataBits::Five,
                        "2" => serialport::DataBits::Six,
                        "3" => serialport::DataBits::Seven,
                        "4" => serialport::DataBits::Eight,
                        _ => {
                            println!("❌ Ошибка: неверный выбор");
                            continue;
                        }
                    };
                    if let Err(e) = port.set_data_bits(data_bits) {
                        println!("❌ Ошибка установки бит данных: {}", e);
                    } else {
                        println!("✅ Биты данных установлены: {:?}", data_bits);
                    }
                }
            }
            "3" => {
                println!("\nВыберите количество стоп-бит:");
                println!("1. 1 стоп-бит");
                println!("2. 2 стоп-бита");
                print!("\nВыберите (1-2): ");
                io::stdout().flush().unwrap();
                let mut stop_input = String::new();
                if io::stdin().read_line(&mut stop_input).is_ok() {
                    let stop_bits = match stop_input.trim() {
                        "1" => serialport::StopBits::One,
                        "2" => serialport::StopBits::Two,
                        _ => {
                            println!("❌ Ошибка: неверный выбор");
                            continue;
                        }
                    };
                    if let Err(e) = port.set_stop_bits(stop_bits) {
                        println!("❌ Ошибка установки стоп-бит: {}", e);
                    } else {
                        println!("✅ Стоп-биты установлены: {:?}", stop_bits);
                    }
                }
            }
            "4" => {
                println!("\nВыберите четность:");
                println!("1. Нет");
                println!("2. Четная");
                println!("3. Нечетная");
                print!("\nВыберите (1-3): ");
                io::stdout().flush().unwrap();
                let mut parity_input = String::new();
                if io::stdin().read_line(&mut parity_input).is_ok() {
                    let parity = match parity_input.trim() {
                        "1" => serialport::Parity::None,
                        "2" => serialport::Parity::Even,
                        "3" => serialport::Parity::Odd,
                        _ => {
                            println!("❌ Ошибка: неверный выбор");
                            continue;
                        }
                    };
                    if let Err(e) = port.set_parity(parity) {
                        println!("❌ Ошибка установки четности: {}", e);
                    } else {
                        println!("✅ Четность установлена: {:?}", parity);
                    }
                }
            }
            "5" => {
                println!("\nВыберите управление потоком:");
                println!("1. Нет");
                println!("2. Аппаратное");
                println!("3. Программное");
                print!("\nВыберите (1-3): ");
                io::stdout().flush().unwrap();
                let mut flow_input = String::new();
                if io::stdin().read_line(&mut flow_input).is_ok() {
                    let flow_control = match flow_input.trim() {
                        "1" => serialport::FlowControl::None,
                        "2" => serialport::FlowControl::Hardware,
                        "3" => serialport::FlowControl::Software,
                        _ => {
                            println!("❌ Ошибка: неверный выбор");
                            continue;
                        }
                    };
                    if let Err(e) = port.set_flow_control(flow_control) {
                        println!("❌ Ошибка установки управления потоком: {}", e);
                    } else {
                        println!("✅ Управление потоком установлено: {:?}", flow_control);
                    }
                }
            }
            "6" => {
                // Получаем текущие настройки порта
                let port_name = port.name().unwrap_or_else(|| String::from("Неизвестный порт"));
                let baud_rate = port.baud_rate().unwrap_or(9600);
                let data_bits = port.data_bits().unwrap_or(serialport::DataBits::Eight);
                let stop_bits = port.stop_bits().unwrap_or(serialport::StopBits::One);
                let parity = port.parity().unwrap_or(serialport::Parity::None);
                let flow_control = port.flow_control().unwrap_or(serialport::FlowControl::None);

                println!("\n✅ Текущие настройки порта: {} @ {} бод, {} бит данных, {} стоп-бит, {} четность, {} поток", 
                    port_name, 
                    baud_rate,
                    match data_bits {
                        serialport::DataBits::Five => "5",
                        serialport::DataBits::Six => "6",
                        serialport::DataBits::Seven => "7",
                        serialport::DataBits::Eight => "8",
                    },
                    match stop_bits {
                        serialport::StopBits::One => "1",
                        serialport::StopBits::Two => "2",
                    },
                    match parity {
                        serialport::Parity::None => "нет",
                        serialport::Parity::Even => "четная",
                        serialport::Parity::Odd => "нечетная",
                    },
                    match flow_control {
                        serialport::FlowControl::None => "нет",
                        serialport::FlowControl::Hardware => "аппаратное",
                        serialport::FlowControl::Software => "программное",
                    }
                );
                
                break;
            },
            _ => println!("⚠️ Неверный выбор. Пожалуйста, выберите 1-6"),
        }
    }
}

fn run_original_version() {
    loop {
        if let Some(port_name) = common::select_port() {
            // Создаем настройки порта
            let mut port_settings = common::get_default_settings(&port_name, 38400);
            
            // Настраиваем параметры по умолчанию
            port_settings = port_settings
                .data_bits(serialport::DataBits::Eight)
                .stop_bits(serialport::StopBits::One)
                .parity(serialport::Parity::None)
                .flow_control(serialport::FlowControl::None);

            println!("\n⚙️ Настройки порта по умолчанию:");
            println!("   • Скорость: 38400 бод");
            println!("   • Биты данных: 8");
            println!("   • Стоп-биты: 1");
            println!("   • Четность: Нет");
            println!("   • Управление потоком: Нет");

            print!("\nХотите изменить настройки? (y/n): ");
            io::stdout().flush().unwrap();
            let mut input = String::new();
            if io::stdin().read_line(&mut input).is_ok() && input.trim().to_lowercase() == "y" {
                loop {
                    println!("\n=== 📋 Настройки порта ===");
                    println!("1. Скорость передачи (бод)");
                    println!("2. Биты данных");
                    println!("3. Стоп-биты");
                    println!("4. Четность");
                    println!("5. Управление потоком");
                    println!("6. Применить настройки и открыть порт");
                    print!("\nВыберите настройку (1-6): ");
                    io::stdout().flush().unwrap();

                    let mut setting_input = String::new();
                    if io::stdin().read_line(&mut setting_input).is_err() {
                        continue;
                    }

                    match setting_input.trim() {
                        "1" => {
                            print!("Введите скорость передачи (бод): ");
                            io::stdout().flush().unwrap();
                            let mut baud_input = String::new();
                            if io::stdin().read_line(&mut baud_input).is_ok() {
                                if let Ok(baud) = baud_input.trim().parse::<u32>() {
                                    port_settings = port_settings.baud_rate(baud);
                                    println!("✅ Скорость установлена: {} бод", baud);
                                } else {
                                    println!("❌ Ошибка: введите корректное число");
                                }
                            }
                        }
                        "2" => {
                            println!("\nВыберите количество бит данных:");
                            println!("1. 5 бит");
                            println!("2. 6 бит");
                            println!("3. 7 бит");
                            println!("4. 8 бит");
                            print!("\nВыберите (1-4): ");
                            io::stdout().flush().unwrap();
                            let mut bits_input = String::new();
                            if io::stdin().read_line(&mut bits_input).is_ok() {
                                let data_bits = match bits_input.trim() {
                                    "1" => serialport::DataBits::Five,
                                    "2" => serialport::DataBits::Six,
                                    "3" => serialport::DataBits::Seven,
                                    "4" => serialport::DataBits::Eight,
                                    _ => {
                                        println!("❌ Ошибка: неверный выбор");
                                        continue;
                                    }
                                };
                                port_settings = port_settings.data_bits(data_bits);
                                println!("✅ Биты данных установлены: {:?}", data_bits);
                            }
                        }
                        "3" => {
                            println!("\nВыберите количество стоп-бит:");
                            println!("1. 1 стоп-бит");
                            println!("2. 2 стоп-бита");
                            print!("\nВыберите (1-2): ");
                            io::stdout().flush().unwrap();
                            let mut stop_input = String::new();
                            if io::stdin().read_line(&mut stop_input).is_ok() {
                                let stop_bits = match stop_input.trim() {
                                    "1" => serialport::StopBits::One,
                                    "2" => serialport::StopBits::Two,
                                    _ => {
                                        println!("❌ Ошибка: неверный выбор");
                                        continue;
                                    }
                                };
                                port_settings = port_settings.stop_bits(stop_bits);
                                println!("✅ Стоп-биты установлены: {:?}", stop_bits);
                            }
                        }
                        "4" => {
                            println!("\nВыберите четность:");
                            println!("1. Нет");
                            println!("2. Четная");
                            println!("3. Нечетная");
                            print!("\nВыберите (1-3): ");
                            io::stdout().flush().unwrap();
                            let mut parity_input = String::new();
                            if io::stdin().read_line(&mut parity_input).is_ok() {
                                let parity = match parity_input.trim() {
                                    "1" => serialport::Parity::None,
                                    "2" => serialport::Parity::Even,
                                    "3" => serialport::Parity::Odd,
                                    _ => {
                                        println!("❌ Ошибка: неверный выбор");
                                        continue;
                                    }
                                };
                                port_settings = port_settings.parity(parity);
                                println!("✅ Четность установлена: {:?}", parity);
                            }
                        }
                        "5" => {
                            println!("\nВыберите управление потоком:");
                            println!("1. Нет");
                            println!("2. Аппаратное");
                            println!("3. Программное");
                            print!("\nВыберите (1-3): ");
                            io::stdout().flush().unwrap();
                            let mut flow_input = String::new();
                            if io::stdin().read_line(&mut flow_input).is_ok() {
                                let flow_control = match flow_input.trim() {
                                    "1" => serialport::FlowControl::None,
                                    "2" => serialport::FlowControl::Hardware,
                                    "3" => serialport::FlowControl::Software,
                                    _ => {
                                        println!("❌ Ошибка: неверный выбор");
                                        continue;
                                    }
                                };
                                port_settings = port_settings.flow_control(flow_control);
                                println!("✅ Управление потоком установлено: {:?}", flow_control);
                            }
                        }
                        "6" => break,
                        _ => println!("⚠️ Неверный выбор. Пожалуйста, выберите 1-6"),
                    }
                }
            }

            // Открываем порт с настроенными параметрами
            let mut port = match port_settings.timeout(Duration::from_millis(50)).open() {
                Ok(port) => port,
                Err(e) => {
                    println!("\n❌ Ошибка открытия порта {}: {}", port_name, e);
                    println!("💡 Возможные причины:");
                    println!("   - Порт используется другой программой");
                    println!("   - Недостаточно прав доступа");
                    println!("   - Устройство было отключено");

                    loop {
                        print!("\nПопробовать выбрать другой порт? (y/n): ");
                        io::stdout().flush().unwrap();

                        let mut input = String::new();
                        if io::stdin().read_line(&mut input).is_err() {
                            continue;
                        }

                        match input.trim().to_lowercase().as_str() {
                            "y" => break,
                            "n" => {
                                println!("\n👋 До свидания!");
                                return;
                            }
                            _ => println!("Пожалуйста, введите 'y' или 'n'"),
                        }
                    }
                    continue;
                }
            };

            // Получаем текущие настройки порта
            let baud_rate = port.baud_rate().unwrap_or(38400);
            let data_bits = port.data_bits().unwrap_or(serialport::DataBits::Eight);
            let stop_bits = port.stop_bits().unwrap_or(serialport::StopBits::One);
            let parity = port.parity().unwrap_or(serialport::Parity::None);
            let flow_control = port.flow_control().unwrap_or(serialport::FlowControl::None);

            println!("\n✅ Соединение установлено: Порт 📌: {} @ {} бод, {} бит данных, {} стоп-бит, {} четность, {} поток", 
                port_name, 
                baud_rate,
                match data_bits {
                    serialport::DataBits::Five => "5",
                    serialport::DataBits::Six => "6",
                    serialport::DataBits::Seven => "7",
                    serialport::DataBits::Eight => "8",
                },
                match stop_bits {
                    serialport::StopBits::One => "1",
                    serialport::StopBits::Two => "2",
                },
                match parity {
                    serialport::Parity::None => "нет",
                    serialport::Parity::Even => "четная",
                    serialport::Parity::Odd => "нечетная",
                },
                match flow_control {
                    serialport::FlowControl::None => "нет",
                    serialport::FlowControl::Hardware => "аппаратное",
                    serialport::FlowControl::Software => "программное",
                }
            );
            println!("\n🔄 Эмулятор готов к работе.");

            let running = Arc::new(AtomicBool::new(true));
            let running_clone = running.clone();
            let mut port_clone = port.try_clone().expect("Failed to clone port");
            
            // Добавляем переменную для приостановки приема данных
            let pause_receiver = Arc::new(AtomicBool::new(false));
            let pause_receiver_clone = pause_receiver.clone();

            let receiver_thread = thread::spawn(move || {
                common::receive_data(&mut port_clone, running_clone, pause_receiver_clone);
            });

            loop {
                show_menu();
                let mut input = String::new();
                if io::stdin().read_line(&mut input).is_err() {
                    println!("❌ Ошибка чтения ввода");
                    continue;
                }
                
                let trimmed_input = input.trim();
                println!("📝 Введено: {}", trimmed_input);

                match trimmed_input {
                    "1" => {
                        // Pause receiver before entering text menu
                        pause_receiver.store(true, Ordering::Relaxed);
                        
                        // Показываем меню
                        println!("\n=== 📋 Меню отправки текстовых сообщений ===");
                        println!("Введите текст для отправки или 'q' для возврата в меню");
                        
                        loop {
                            print!("> ");
                            io::stdout().flush().unwrap();
                            
                            let mut input = String::new();
                            if io::stdin().read_line(&mut input).is_err() {
                                println!("❌ Ошибка чтения ввода");
                                continue;
                            }
                            
                            let trimmed_input = input.trim();
                            
                            if trimmed_input.eq_ignore_ascii_case("q") {
                                break;
                            }
                            
                            if !trimmed_input.is_empty() {
                                common::send_text_message(&mut port, trimmed_input);
                            }
                        }
                        
                        // Resume receiver after exiting menu
                        pause_receiver.store(false, Ordering::Relaxed);
                    },
                    "2" => {
                        // Pause receiver before entering HEX menu
                        pause_receiver.store(true, Ordering::Relaxed);
                        
                        // Показываем меню
                        println!("\n=== 📋 Меню отправки HEX данных ===");
                        println!("Введите HEX данные (например: FF 00 AB) или 'q' для возврата в меню");
                        
                        loop {
                            print!("> ");
                            io::stdout().flush().unwrap();
                            
                            let mut input = String::new();
                            if io::stdin().read_line(&mut input).is_err() {
                                println!("❌ Ошибка чтения ввода");
                                continue;
                            }
                            
                            let trimmed_input = input.trim();
                            
                            if trimmed_input.eq_ignore_ascii_case("q") {
                                break;
                            }
                            
                            if !trimmed_input.is_empty() {
                                common::send_hex_data(&mut port, trimmed_input);
                            }
                        }
                        
                        // Resume receiver after exiting HEX menu
                        pause_receiver.store(false, Ordering::Relaxed);
                    },
                    "3" => {
                        // Pause receiver before entering HEX+CRC menu
                        pause_receiver.store(true, Ordering::Relaxed);
                        
                        // Показываем меню
                        println!("\n=== 📋 Меню отправки HEX данных с CRC16 ===");
                        println!("Введите HEX данные для отправки с CRC16 или 'q' для возврата в меню");
                        
                        loop {
                            print!("> ");
                            io::stdout().flush().unwrap();
                            
                            let mut input = String::new();
                            if io::stdin().read_line(&mut input).is_err() {
                                println!("❌ Ошибка чтения ввода");
                                continue;
                            }
                            
                            let trimmed_input = input.trim();
                            
                            if trimmed_input.eq_ignore_ascii_case("q") {
                                break;
                            }
                            
                            if !trimmed_input.is_empty() {
                                common::send_hex_data_with_crc(&mut port, trimmed_input);
                            }
                        }
                        
                        // Resume receiver after exiting HEX+CRC menu
                        pause_receiver.store(false, Ordering::Relaxed);
                    },
                    "4" => {
                        println!("🔄 Переход в меню настроек порта...");
                        configure_port_settings(&mut port);
                    }
                    "5" => {
                        common::clear_screen();
                    }
                    "6" => {
                        println!("\n👋 До свидания!");
                        running.store(false, Ordering::Relaxed);
                        break;
                    }
                    _ => println!("⚠️ Неверный выбор. Пожалуйста, выберите 1-6"),
                }
            }

            if let Err(e) = receiver_thread.join() {
                eprintln!("Ошибка в потоке приема: {:?}", e);
            }
            break;
        } else {
            println!("❌ Выход: последовательный порт не выбран!");
            break;
        }
    }
}

fn main() {
    println!("=== VirtualComPy2R ===");
    println!("1. Стандартная версия");
    println!("2. Версия с командами ТАКТ");
    print!("\nВыберите версию (1-2): ");
    io::stdout().flush().unwrap();

    let mut input = String::new();
    if io::stdin().read_line(&mut input).is_err() {
        return;
    }

    match input.trim() {
        "1" => {
            run_original_version();
        },
        "2" => {
            main_takt::main();
        },
        _ => {
            println!("⚠️ Неверный выбор. Пожалуйста, выберите 1 или 2");
        }
    }
} 