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

use super::{BaseFields, MediaFields, NoteFields};

// ==================== SERVICE SESSIONS ====================

/// Active work session during a service
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ServiceSession {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub service_id: Uuid,
    pub account_id: Uuid,
    pub account_address_id: Uuid,
    pub customer_id: Uuid,
    pub scope_id: Option<Uuid>,
    pub start: DateTime<Utc>,
    pub end: Option<DateTime<Utc>>,
    pub created_by_id: Uuid,
    pub closed_by_id: Option<Uuid>,
    pub date: NaiveDate,
}

impl ServiceSession {
    /// Check if session is still active (not ended)
    pub fn is_active(&self) -> bool {
        self.end.is_none()
    }

    /// Calculate duration in seconds
    pub fn duration_seconds(&self) -> Option<i64> {
        self.end.map(|end| (end - self.start).num_seconds())
    }
}

/// Note attached to a service session
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ServiceSessionNote {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub session_id: Uuid,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub note: NoteFields,
}

/// Image attached to a service session
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ServiceSessionImage {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub session_id: Uuid,
    pub title: Option<String>,
    /// S3 path to the original image
    pub image: String,
    /// S3 path to the thumbnail
    pub thumbnail: Option<String>,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub media: MediaFields,
}

/// Video attached to a service session
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ServiceSessionVideo {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub session_id: Uuid,
    pub title: Option<String>,
    /// S3 path to the video file
    pub video: String,
    /// S3 path to the thumbnail
    pub thumbnail: Option<String>,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub media: MediaFields,
    pub duration_seconds: Option<i32>,
    pub file_size_bytes: Option<i64>,
}

/// Task completion record for a service
/// Note: Linked to sessions via service_session_completed_tasks junction table
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ServiceTaskCompletion {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub service_id: Uuid,
    pub task_id: Uuid,
    pub account_address_id: Option<Uuid>,
    pub completed_by_id: Uuid,
    pub completed_at: DateTime<Utc>,
    pub year: i32,
    pub month: i32,
    pub notes: Option<String>,
}

// ==================== PROJECT SESSIONS ====================

/// Active work session during a project
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ProjectSession {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub project_id: Uuid,
    pub account_id: Option<Uuid>,
    pub account_address_id: Option<Uuid>,
    pub customer_id: Uuid,
    pub scope_id: Option<Uuid>,
    pub start: DateTime<Utc>,
    pub end: Option<DateTime<Utc>>,
    pub created_by_id: Uuid,
    pub closed_by_id: Option<Uuid>,
    pub date: NaiveDate,
}

impl ProjectSession {
    /// Check if session is still active (not ended)
    pub fn is_active(&self) -> bool {
        self.end.is_none()
    }

    /// Calculate duration in seconds
    pub fn duration_seconds(&self) -> Option<i64> {
        self.end.map(|end| (end - self.start).num_seconds())
    }
}

/// Note attached to a project session
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ProjectSessionNote {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub session_id: Uuid,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub note: NoteFields,
}

/// Image attached to a project session
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ProjectSessionImage {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub session_id: Uuid,
    pub title: Option<String>,
    /// S3 path to the original image
    pub image: String,
    /// S3 path to the thumbnail
    pub thumbnail: Option<String>,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub media: MediaFields,
}

/// Video attached to a project session
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ProjectSessionVideo {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub session_id: Uuid,
    pub title: Option<String>,
    /// S3 path to the video file
    pub video: String,
    /// S3 path to the thumbnail
    pub thumbnail: Option<String>,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub media: MediaFields,
    pub duration_seconds: Option<i32>,
    pub file_size_bytes: Option<i64>,
}

/// Task completion record for a project
/// Note: Linked to sessions via project_session_completed_tasks junction table
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ProjectTaskCompletion {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub project_id: Uuid,
    pub task_id: Uuid,
    pub account_id: Option<Uuid>,
    pub account_address_id: Option<Uuid>,
    pub completed_by_id: Uuid,
    pub completed_at: DateTime<Utc>,
    pub notes: Option<String>,
}
