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

use rust_decimal::Decimal;

use super::{BaseFields, ContactFields, EntityStatus, ReportStatus, TeamRole};

/// Internal team member profile
/// Note: base.id IS the Kratos identity UUID - no separate ory_kratos_id
/// This allows Oathkeeper's X-User-ID header to be used directly for profile lookup
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct TeamProfile {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub contact: ContactFields,
    pub email: Option<String>,
    pub role: TeamRole,
    pub status: EntityStatus,
    pub notes: Option<String>,
}

impl TeamProfile {
    pub fn full_name(&self) -> String {
        self.contact.full_name()
    }

    /// Check if this profile has at least the given role level
    pub fn has_minimum_role(&self, role: TeamRole) -> bool {
        let self_level = match self.role {
            TeamRole::Admin => 3,
            TeamRole::TeamLeader => 2,
            TeamRole::TeamMember => 1,
        };

        let required_level = match role {
            TeamRole::Admin => 3,
            TeamRole::TeamLeader => 2,
            TeamRole::TeamMember => 1,
        };

        self_level >= required_level
    }
}

/// External customer profile
/// Note: base.id IS the Kratos identity UUID - no separate ory_kratos_id
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct CustomerProfile {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub contact: ContactFields,
    pub email: Option<String>,
    pub status: EntityStatus,
    pub notes: Option<String>,
}

impl CustomerProfile {
    pub fn full_name(&self) -> String {
        self.contact.full_name()
    }
}

/// Many-to-many: CustomerProfile access to Customer (join table)
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct CustomerProfileAccess {
    pub id: Uuid,
    pub customer_profile_id: Uuid,
    pub customer_id: Uuid,
    pub created_at: DateTime<Utc>,
}

/// Team member work report for a pay period
/// Contains services and projects worked, with snapshot labor amounts for payroll
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Report {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub team_profile_id: Uuid,
    pub start_date: chrono::NaiveDate,
    pub end_date: chrono::NaiveDate,
    pub status: ReportStatus,
}

/// Report-Service association with snapshot labor share
/// labor_share is calculated and stored when added - immutable for payroll accuracy
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ReportService {
    pub id: Uuid,
    pub report_id: Uuid,
    pub service_id: Uuid,
    pub labor_share: Decimal,
    pub created_at: DateTime<Utc>,
}

/// Report-Project association with snapshot labor share
/// labor_share is calculated and stored when added - immutable for payroll accuracy
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ReportProject {
    pub id: Uuid,
    pub report_id: Uuid,
    pub project_id: Uuid,
    pub labor_share: Decimal,
    pub created_at: DateTime<Utc>,
}
