use crate::config::{AppConfig, Environment, ServiceType};
use crate::error::Result;
use clap::{Args, Subcommand};
use crossterm::{
    event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
    execute,
    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::{
    backend::CrosstermBackend,
    layout::{Constraint, Direction, Layout, Rect},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, List, ListItem, Paragraph, Row, Table},
    Terminal,
};
use std::io;
use std::time::Duration;

#[derive(Args)]
pub struct MonitorCommand {
    #[command(subcommand)]
    command: Option<MonitorSubcommand>,

    /// Environment (production/stage/development)
    #[arg(long)]
    env: Option<String>,
}

#[derive(Subcommand)]
enum MonitorSubcommand {
    /// Display dashboard with real-time monitoring
    Dashboard(DashboardCommand),
}

#[derive(Args)]
struct DashboardCommand {
    /// Refresh interval in seconds
    #[arg(long, default_value = "5")]
    interval: u64,
}

impl MonitorCommand {
    /// 创建默认的 MonitorCommand（启动 dashboard）
    pub fn default_dashboard() -> Self {
        Self {
            command: None,
            env: None,
        }
    }

    pub async fn execute(&self, config: &AppConfig) -> Result<()> {
        match &self.command {
            Some(MonitorSubcommand::Dashboard(cmd)) => cmd.execute(config).await,
            None => {
                // 默认启动 dashboard
                DashboardCommand { interval: 5 }.execute(config).await
            }
        }
    }
}

struct App {
    env: Environment,
    services: Vec<ServiceInfo>,
    selected: usize,
    last_update: std::time::Instant,
}

struct ServiceInfo {
    name: String,
    service_type: ServiceType,
    status: ServiceStatus,
    response_time: Option<String>,
    cpu: Option<String>,
    memory: Option<String>,
}

#[derive(Clone, Copy, PartialEq)]
enum ServiceStatus {
    Healthy,
    Unhealthy,
    Error,
    Unknown,
}

impl ServiceStatus {
    fn to_string(&self) -> &str {
        match self {
            ServiceStatus::Healthy => "✓ 健康",
            ServiceStatus::Unhealthy => "✗ 不健康",
            ServiceStatus::Error => "✗ 错误",
            ServiceStatus::Unknown => "? 未知",
        }
    }

    fn color(&self) -> Color {
        match self {
            ServiceStatus::Healthy => Color::Green,
            ServiceStatus::Unhealthy => Color::Yellow,
            ServiceStatus::Error => Color::Red,
            ServiceStatus::Unknown => Color::Gray,
        }
    }
}

impl DashboardCommand {
    async fn execute(&self, config: &AppConfig) -> Result<()> {
        // 设置终端
        enable_raw_mode()?;
        let mut stdout = io::stdout();
        execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
        let backend = CrosstermBackend::new(stdout);
        let mut terminal = Terminal::new(backend)?;

        // 创建应用状态
        let env = config.get_environment();
        let services = config.get_all_services();

        let mut app = App {
            env,
            services: services
                .iter()
                .map(|s| ServiceInfo {
                    name: s.name.clone(),
                    service_type: s.service_type,
                    status: ServiceStatus::Unknown,
                    response_time: None,
                    cpu: None,
                    memory: None,
                })
                .collect(),
            selected: 0,
            last_update: std::time::Instant::now(),
        };

        // 主循环
        let result = run_app(&mut terminal, &mut app, self.interval, config).await;

        // 恢复终端
        disable_raw_mode()?;
        execute!(
            terminal.backend_mut(),
            LeaveAlternateScreen,
            DisableMouseCapture
        )?;
        terminal.show_cursor()?;

        result
    }
}

async fn run_app(
    terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
    app: &mut App,
    interval: u64,
    config: &AppConfig,
) -> Result<()> {
    let refresh_interval = Duration::from_secs(interval);
    let mut last_refresh = std::time::Instant::now();

    loop {
        // 绘制 UI
        terminal.draw(|f| ui(f, app))?;

        // 检查是否需要刷新数据
        if last_refresh.elapsed() >= refresh_interval {
            refresh_data(app, config).await;
            last_refresh = std::time::Instant::now();
        }

        // 处理输入事件 (100ms 超时)
        if event::poll(Duration::from_millis(100))? {
            if let Event::Key(key) = event::read()? {
                match key.code {
                    KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
                    KeyCode::Char('r') => {
                        refresh_data(app, config).await;
                        last_refresh = std::time::Instant::now();
                    }
                    KeyCode::Up | KeyCode::Char('k') => {
                        if app.selected > 0 {
                            app.selected -= 1;
                        }
                    }
                    KeyCode::Down | KeyCode::Char('j') => {
                        if app.selected < app.services.len() - 1 {
                            app.selected += 1;
                        }
                    }
                    _ => {}
                }
            }
        }
    }
}

fn ui(f: &mut ratatui::Frame, app: &App) {
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .margin(1)
        .constraints(
            [
                Constraint::Length(3),  // 标题
                Constraint::Min(10),    // 服务列表
                Constraint::Length(3),  // 帮助信息
            ]
            .as_ref(),
        )
        .split(f.area());

    // 标题
    let title = Paragraph::new(format!(
        "Optima Ops Monitor - {} 环境 | 上次更新: {:?}秒前",
        app.env.as_str(),
        app.last_update.elapsed().as_secs()
    ))
    .style(Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD))
    .block(Block::default().borders(Borders::ALL).title("监控面板"));
    f.render_widget(title, chunks[0]);

    // 服务列表
    render_services_table(f, app, chunks[1]);

    // 帮助信息
    let help = Paragraph::new("↑/k: 上 | ↓/j: 下 | r: 刷新 | q/ESC: 退出")
        .style(Style::default().fg(Color::Gray))
        .block(Block::default().borders(Borders::ALL).title("快捷键"));
    f.render_widget(help, chunks[2]);
}

fn render_services_table(f: &mut ratatui::Frame, app: &App, area: Rect) {
    let header_cells = ["服务名称", "类型", "状态", "响应时间", "CPU", "内存"]
        .iter()
        .map(|h| {
            ratatui::widgets::Cell::from(*h).style(
                Style::default()
                    .fg(Color::Yellow)
                    .add_modifier(Modifier::BOLD),
            )
        });
    let header = Row::new(header_cells).height(1).bottom_margin(1);

    let rows = app.services.iter().enumerate().map(|(i, service)| {
        let style = if i == app.selected {
            Style::default()
                .bg(Color::DarkGray)
                .add_modifier(Modifier::BOLD)
        } else {
            Style::default()
        };

        let cells = vec![
            ratatui::widgets::Cell::from(service.name.clone()),
            ratatui::widgets::Cell::from(match service.service_type {
                ServiceType::Core => "核心",
                ServiceType::MCP => "MCP",
            }),
            ratatui::widgets::Cell::from(service.status.to_string())
                .style(Style::default().fg(service.status.color())),
            ratatui::widgets::Cell::from(
                service
                    .response_time
                    .as_ref()
                    .map(|s| s.as_str())
                    .unwrap_or("-"),
            ),
            ratatui::widgets::Cell::from(
                service.cpu.as_ref().map(|s| s.as_str()).unwrap_or("-"),
            ),
            ratatui::widgets::Cell::from(
                service
                    .memory
                    .as_ref()
                    .map(|s| s.as_str())
                    .unwrap_or("-"),
            ),
        ];

        Row::new(cells).height(1).style(style)
    });

    let widths = [
        Constraint::Percentage(25),
        Constraint::Percentage(10),
        Constraint::Percentage(15),
        Constraint::Percentage(15),
        Constraint::Percentage(15),
        Constraint::Percentage(20),
    ];

    let table = Table::new(rows, widths)
        .header(header)
        .block(
            Block::default()
                .borders(Borders::ALL)
                .title(format!("服务列表 ({} 个服务)", app.services.len())),
        )
        .highlight_style(
            Style::default()
                .bg(Color::DarkGray)
                .add_modifier(Modifier::BOLD),
        );

    f.render_widget(table, area);
}

async fn refresh_data(app: &mut App, config: &AppConfig) {
    // 模拟数据刷新 (实际应该调用 services health 等命令)
    // 这里简化处理,实际项目中应该调用真实的 API

    use rand::Rng;
    let mut rng = rand::thread_rng();

    for service in &mut app.services {
        // 随机生成状态 (演示用)
        let random = rng.gen_range(0..100);
        service.status = if random < 85 {
            ServiceStatus::Healthy
        } else if random < 95 {
            ServiceStatus::Unhealthy
        } else {
            ServiceStatus::Error
        };

        service.response_time = Some(format!("{}ms", rng.gen_range(50..500)));
        service.cpu = Some(format!("{:.1}%", rng.gen_range(1.0..50.0)));
        service.memory = Some(format!("{}MB", rng.gen_range(100..800)));
    }

    app.last_update = std::time::Instant::now();
}
