use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};

/// API response wrapper used by the orchestrator
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiResponse<T> {
    pub success: bool,
    pub data: Option<T>,
    pub error: Option<String>,
}

/// Task status enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TaskStatus {
    Pending,
    Running,
    Completed,
    Failed,
    Cancelled,
}

/// Workflow task representation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowTask {
    pub id: String,
    pub name: String,
    pub command: String,
    pub args: Vec<String>,
    pub dependencies: Vec<String>,
    pub status: TaskStatus,
    pub created_at: DateTime<Utc>,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub output: Option<String>,
    pub error: Option<String>,
}

/// Server creation workflow request - Complete auditable unit
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateServerWorkflow {
    pub infra: String,
    pub settings: String,
    pub servers: Vec<String>,
    pub check_mode: bool,
    pub wait: bool,
    // Template and execution context
    #[serde(default)]
    pub template_path: Option<String>,      // Path to template used: /provisioning/extensions/providers/.../hetzner_servers.j2
    #[serde(default)]
    pub template_vars_compressed: Option<String>,  // Gzip+Base64 encoded template variables
    // Generated script (compressed for transmission)
    #[serde(default)]
    pub script_compressed: Option<String>,  // Gzip+Base64 encoded script
    #[serde(default)]
    pub script_encoding: Option<String>,    // Encoding type: "gzip+base64"
    // Compression metrics
    #[serde(default)]
    pub compression_ratio: Option<f32>,     // Overall compression ratio
    #[serde(default)]
    pub original_size: Option<u64>,         // Original script size
    #[serde(default)]
    pub compressed_size: Option<u64>,       // Compressed size
}

/// Task service workflow request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskservWorkflow {
    pub infra: String,
    pub settings: String,
    pub taskserv: String,
    pub operation: String, // create, delete, generate, check-updates
    pub check_mode: bool,
    pub wait: bool,
}

/// Cluster workflow request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClusterWorkflow {
    pub infra: String,
    pub settings: String,
    pub cluster_type: String,
    pub operation: String, // create, delete
    pub check_mode: bool,
    pub wait: bool,
}

/// Unified component lifecycle workflow request.
/// Submitted to `/api/v1/workflows/component/{op}`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentWorkflow {
    pub workspace: String,
    pub infra: String,
    pub component: String,
    pub server: String,
    #[serde(default)]
    pub namespace: Option<String>,
    #[serde(default = "default_ssh_user")]
    pub ssh_user: String,
    #[serde(default)]
    pub ssh_key_path: Option<String>,
    pub settings: String,
    #[serde(default)]
    pub check_mode: bool,
    pub provisioning: String,
}

fn default_ssh_user() -> String {
    "root".to_string()
}

/// Batch operation request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchOperationRequest {
    pub workflow_id: String,
    pub operations: Vec<BatchOperation>,
    pub parallel_limit: Option<usize>,
    pub rollback_enabled: Option<bool>,
}

/// Individual batch operation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchOperation {
    pub id: String,
    pub operation_type: String,
    pub provider: String,
    pub dependencies: Vec<String>,
    pub config: serde_json::Value,
}

/// Batch operation result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchOperationResult {
    pub operation_id: String,
    pub status: String,
    pub message: String,
}

/// Workflow execution state
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowExecutionState {
    pub id: String,
    pub status: String,
    pub progress: f64,
    pub current_operation: Option<String>,
    pub completed_operations: Vec<String>,
    pub failed_operations: Vec<String>,
    pub created_at: DateTime<Utc>,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
}

/// System health status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemHealthStatus {
    pub overall_status: String,
    pub checks: Vec<HealthCheck>,
    pub last_updated: DateTime<Utc>,
}

/// Individual health check
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthCheck {
    pub name: String,
    pub status: String,
    pub message: Option<String>,
    pub last_check: DateTime<Utc>,
}

/// Progress information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProgressInfo {
    pub workflow_id: String,
    pub current_step: String,
    pub progress_percentage: f64,
    pub estimated_completion: Option<DateTime<Utc>>,
    pub step_details: Vec<StepDetail>,
}

/// Step detail information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StepDetail {
    pub step_name: String,
    pub status: String,
    pub progress: f64,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
}

/// System metrics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemMetrics {
    pub cpu_usage: f64,
    pub memory_usage: f64,
    pub disk_usage: f64,
    pub active_workflows: u32,
    pub completed_workflows: u32,
    pub failed_workflows: u32,
    pub uptime_seconds: u64,
}

/// State snapshot
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StateSnapshot {
    pub id: String,
    pub workflow_id: String,
    pub timestamp: DateTime<Utc>,
    pub state_data: serde_json::Value,
}

/// Checkpoint information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Checkpoint {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub created_at: DateTime<Utc>,
    pub workflow_states: Vec<String>,
}

/// Create checkpoint request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateCheckpointRequest {
    pub name: String,
    pub description: Option<String>,
}

/// Rollback request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RollbackRequest {
    pub checkpoint_id: Option<String>,
    pub operation_ids: Option<Vec<String>>,
}

/// Rollback result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RollbackResult {
    pub success: bool,
    pub operations_executed: u32,
    pub operations_failed: u32,
    pub rollback_id: String,
    pub message: String,
}

/// Rollback statistics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RollbackStatistics {
    pub total_rollbacks: u32,
    pub successful_rollbacks: u32,
    pub failed_rollbacks: u32,
    pub average_rollback_time_ms: u64,
    pub checkpoints_created: u32,
}

/// State manager statistics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StateManagerStatistics {
    pub total_snapshots: u32,
    pub active_workflows: u32,
    pub storage_size_bytes: u64,
    pub average_snapshot_size_bytes: u64,
}
