use async_graphql::{Enum, SimpleObject, Union};
use chrono::{DateTime, Utc};
use uuid::Uuid;

use crate::graphql::types::EntityStatusType;
use crate::models::{CustomerProfile, TeamProfile, TeamRole};

/// GraphQL enum for team member roles
#[derive(Enum, Copy, Clone, Eq, PartialEq)]
pub enum TeamRoleType {
    Admin,
    TeamLeader,
    TeamMember,
}

impl From<TeamRole> for TeamRoleType {
    fn from(role: TeamRole) -> Self {
        match role {
            TeamRole::Admin => TeamRoleType::Admin,
            TeamRole::TeamLeader => TeamRoleType::TeamLeader,
            TeamRole::TeamMember => TeamRoleType::TeamMember,
        }
    }
}

impl From<TeamRoleType> for TeamRole {
    fn from(role: TeamRoleType) -> Self {
        match role {
            TeamRoleType::Admin => TeamRole::Admin,
            TeamRoleType::TeamLeader => TeamRole::TeamLeader,
            TeamRoleType::TeamMember => TeamRole::TeamMember,
        }
    }
}

/// Team member profile (internal user)
#[derive(SimpleObject)]
pub struct TeamProfileType {
    pub id: Uuid,
    pub first_name: String,
    pub last_name: String,
    pub full_name: String,
    pub email: Option<String>,
    pub phone: Option<String>,
    pub role: TeamRoleType,
    pub status: EntityStatusType,
    pub notes: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

impl From<TeamProfile> for TeamProfileType {
    fn from(profile: TeamProfile) -> Self {
        Self {
            id: profile.base.id,
            first_name: profile.contact.first_name.clone(),
            last_name: profile.contact.last_name.clone(),
            full_name: profile.full_name(),
            email: profile.email,
            phone: profile.contact.phone,
            role: profile.role.into(),
            status: profile.status.into(),
            notes: profile.notes,
            created_at: profile.base.created_at,
            updated_at: profile.base.updated_at,
        }
    }
}

/// Customer info for CustomerProfileType
#[derive(SimpleObject)]
pub struct CustomerInfo {
    pub id: Uuid,
    pub name: String,
}

/// Customer profile (external user)
#[derive(SimpleObject)]
pub struct CustomerProfileType {
    pub id: Uuid,
    pub first_name: String,
    pub last_name: String,
    pub full_name: String,
    pub email: Option<String>,
    pub phone: Option<String>,
    pub status: EntityStatusType,
    pub notes: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub customers: Vec<CustomerInfo>,
}

impl CustomerProfileType {
    pub fn from_profile(profile: CustomerProfile, customers: Vec<CustomerInfo>) -> Self {
        Self {
            id: profile.base.id,
            first_name: profile.contact.first_name.clone(),
            last_name: profile.contact.last_name.clone(),
            full_name: profile.full_name(),
            email: profile.email,
            phone: profile.contact.phone,
            status: profile.status.into(),
            notes: profile.notes,
            created_at: profile.base.created_at,
            updated_at: profile.base.updated_at,
            customers,
        }
    }
}

impl From<CustomerProfile> for CustomerProfileType {
    fn from(profile: CustomerProfile) -> Self {
        Self {
            id: profile.base.id,
            first_name: profile.contact.first_name.clone(),
            last_name: profile.contact.last_name.clone(),
            full_name: profile.full_name(),
            email: profile.email,
            phone: profile.contact.phone,
            status: profile.status.into(),
            notes: profile.notes,
            created_at: profile.base.created_at,
            updated_at: profile.base.updated_at,
            customers: vec![],
        }
    }
}

/// Union type for the `me` query - can be either team or customer profile
#[derive(Union)]
pub enum ProfileType {
    TeamProfile(TeamProfileType),
    CustomerProfile(CustomerProfileType),
}
