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

use super::{AddressFields, BaseFields, ContactFields, EntityStatus};

/// Customer's business location or division
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Account {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub customer_id: Uuid,
    pub name: String,
    pub status: EntityStatus,
    pub start_date: Option<NaiveDate>,
    pub end_date: Option<NaiveDate>,
}

impl Account {
    /// Check if account is currently active based on dates
    pub fn is_active(&self) -> bool {
        if self.status != EntityStatus::Active {
            return false;
        }

        let today = chrono::Utc::now().date_naive();

        if let Some(start) = self.start_date {
            if today < start {
                return false;
            }
        }

        if let Some(end) = self.end_date {
            if today > end {
                return false;
            }
        }

        true
    }
}

/// Physical location for an account
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct AccountAddress {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub account_id: Uuid,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub address: AddressFields,
    pub is_active: bool,
    pub is_primary: bool,
    pub name: Option<String>,
    pub notes: Option<String>,
}

/// Contact person at an account
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct AccountContact {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub account_id: Uuid,
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub contact: ContactFields,
    pub email: Option<String>,
    pub is_active: bool,
    pub is_primary: bool,
    pub notes: Option<String>,
}

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