use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;

use super::{BaseFields, TeamRole};

// ==================== MCP SERVER REGISTRY ====================

/// MCP transport type for server connections
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum McpTransportType {
    Stdio,
    Sse,
    Websocket,
}

impl McpTransportType {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Stdio => "stdio",
            Self::Sse => "sse",
            Self::Websocket => "websocket",
        }
    }
}

/// MCP tool execution status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum McpExecutionStatus {
    Pending,
    Running,
    Success,
    Error,
}

impl McpExecutionStatus {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Pending => "pending",
            Self::Running => "running",
            Self::Success => "success",
            Self::Error => "error",
        }
    }
}

/// MCP Server definition
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct McpServer {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub name: String,
    pub description: Option<String>,
    /// Transport type: 'stdio', 'sse', 'websocket'
    pub transport_type: String,
    /// For stdio: command to run
    pub command: Option<String>,
    /// Command arguments (JSON array)
    pub args: serde_json::Value,
    /// Environment variables (JSON object)
    pub env: serde_json::Value,
    /// For sse/websocket: URL to connect to
    pub url: Option<String>,
    pub is_active: bool,
    /// Rate limit: max calls per minute
    pub rate_limit_per_minute: Option<i32>,
    /// Rate limit: max calls per hour
    pub rate_limit_per_hour: Option<i32>,
}

/// MCP Tool provided by a server
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct McpTool {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub server_id: Uuid,
    pub name: String,
    pub description: Option<String>,
    /// JSON Schema for tool input
    pub input_schema: serde_json::Value,
    pub is_active: bool,
}

/// Role-based permission for an MCP tool
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct McpToolPermission {
    pub id: Uuid,
    pub created_at: DateTime<Utc>,
    pub tool_id: Uuid,
    pub role: TeamRole,
}

/// User-specific permission override for an MCP tool
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct McpToolUserPermission {
    pub id: Uuid,
    pub created_at: DateTime<Utc>,
    pub tool_id: Uuid,
    pub team_profile_id: Uuid,
    /// Explicit allow/deny (overrides role-based permission)
    pub is_allowed: bool,
}

/// MCP Tool execution log entry
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct McpToolExecution {
    pub id: Uuid,
    pub created_at: DateTime<Utc>,
    pub tool_id: Uuid,
    pub team_profile_id: Uuid,
    pub chat_message_id: Option<Uuid>,
    /// Input provided to the tool (JSON)
    pub input: serde_json::Value,
    /// Output from the tool (JSON)
    pub output: Option<serde_json::Value>,
    /// Error message if execution failed
    pub error: Option<String>,
    pub started_at: DateTime<Utc>,
    pub completed_at: Option<DateTime<Utc>>,
    pub duration_ms: Option<i32>,
    /// Status: 'pending', 'running', 'success', 'error'
    pub status: String,
}
