// Core domain models for VAPORA v1.0
// Phase 1: Complete type definitions for backend

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

// ============================================================================
// Project Models
// ============================================================================

/// Project model
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Project {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub tenant_id: String,
    pub title: String,
    pub description: Option<String>,
    pub status: ProjectStatus,
    #[serde(default)]
    pub features: Vec<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Project status enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ProjectStatus {
    Active,
    Archived,
    Completed,
}

// ============================================================================
// Task Models
// ============================================================================

/// Task model for Kanban board
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Task {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub tenant_id: String,
    pub project_id: String,
    pub title: String,
    pub description: Option<String>,
    pub status: TaskStatus,
    pub assignee: String,
    pub priority: TaskPriority,
    pub task_order: i32,
    pub feature: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Task status for Kanban columns
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum TaskStatus {
    Todo,
    Doing,
    Review,
    Done,
}

/// Task priority levels
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub enum TaskPriority {
    Low,
    Medium,
    High,
    Critical,
}

// ============================================================================
// Agent Models
// ============================================================================

/// Agent registry model (12 specialized roles)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Agent {
    pub id: String,
    pub role: AgentRole,
    pub name: String,
    pub version: String,
    pub status: AgentStatus,
    #[serde(default)]
    pub capabilities: Vec<String>,
    #[serde(default)]
    pub skills: Vec<String>,
    pub llm_provider: String,
    pub llm_model: String,
    pub max_concurrent_tasks: u32,
    pub created_at: DateTime<Utc>,
}

/// Agent role enumeration (12 roles as per VAPORA spec)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AgentRole {
    Architect,
    Developer,
    CodeReviewer,
    Tester,
    Documenter,
    Marketer,
    Presenter,
    DevOps,
    Monitor,
    Security,
    ProjectManager,
    DecisionMaker,
}

/// Agent status
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum AgentStatus {
    Active,
    Inactive,
    Updating,
    Error,
}

/// Agent instance (runtime pod)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentInstance {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub agent_id: String,
    pub pod_id: String,
    pub ip: Option<String>,
    pub port: u16,
    pub start_time: DateTime<Utc>,
    pub last_heartbeat: DateTime<Utc>,
    pub tasks_completed: u32,
    pub uptime_percentage: f64,
    pub status: AgentInstanceStatus,
}

/// Agent instance status
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum AgentInstanceStatus {
    Running,
    Stopped,
    Error,
}

// ============================================================================
// User Models
// ============================================================================

/// User model
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub email: String,
    pub username: String,
    #[serde(skip_serializing)]
    pub password_hash: String,
    #[serde(default)]
    pub roles: Vec<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

// ============================================================================
// Workflow Models
// ============================================================================

/// Workflow definition
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Workflow {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub tenant_id: String,
    pub name: String,
    pub description: Option<String>,
    pub status: WorkflowStatus,
    pub definition: serde_json::Value,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Workflow status
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum WorkflowStatus {
    Draft,
    Active,
    Paused,
    Completed,
    Failed,
}

/// Workflow step execution
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowStep {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub workflow_id: String,
    pub step_id: String,
    pub step_name: String,
    pub agent_id: Option<String>,
    pub status: WorkflowStepStatus,
    pub result: Option<serde_json::Value>,
    pub error_message: Option<String>,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub created_at: DateTime<Utc>,
}

/// Workflow step status
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum WorkflowStepStatus {
    Pending,
    InProgress,
    Completed,
    Failed,
    Skipped,
}

// ============================================================================
// Document Models (RAG)
// ============================================================================

/// Document for RAG system
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Document {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub tenant_id: String,
    pub project_id: Option<String>,
    pub title: String,
    pub content: String,
    pub content_type: DocumentContentType,
    #[serde(default)]
    pub metadata: serde_json::Value,
    pub embedding: Option<Vec<f32>>,
    pub source_path: Option<String>,
    #[serde(default)]
    pub tags: Vec<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Document content type
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DocumentContentType {
    Markdown,
    Code,
    Text,
    Json,
}

// ============================================================================
// Proposal Models (Risk-Based Approval)
// ============================================================================

/// Proposal model for task approval gates
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Proposal {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub tenant_id: String,
    pub project_id: String,
    pub task_id: String,
    pub agent_id: String,
    pub title: String,
    pub description: Option<String>,
    pub status: ProposalStatus,
    pub risk_level: RiskLevel,
    pub plan_details: PlanDetails,
    pub created_at: DateTime<Utc>,
    pub submitted_at: Option<DateTime<Utc>>,
    pub reviewed_at: Option<DateTime<Utc>>,
    pub executed_at: Option<DateTime<Utc>>,
}

/// Proposal status enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ProposalStatus {
    Proposed,
    Approved,
    Rejected,
    Executed,
}

/// Risk level for proposals
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub enum RiskLevel {
    Low,
    Medium,
    High,
}

/// Detailed plan information for proposals
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PlanDetails {
    pub description: String,
    pub affected_resources: Vec<String>,
    pub estimated_cost: Option<f64>,
    pub confidence: f64,
    pub rollback_strategy: Option<String>,
    pub metadata: serde_json::Value,
}

/// Review feedback for proposals
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ProposalReview {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub proposal_id: String,
    pub reviewer_id: String,
    pub feedback: String,
    pub approved: bool,
    pub created_at: DateTime<Utc>,
}
