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

use super::{BaseFields, InvoiceStatus, PaymentType};

/// Labor rate for an account address
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Labor {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub account_address_id: Uuid,
    pub amount: Decimal,
    pub start_date: NaiveDate,
    pub end_date: Option<NaiveDate>,
}

impl Labor {
    /// Check if labor rate is active on a given date
    pub fn is_active_on(&self, date: NaiveDate) -> bool {
        if date < self.start_date {
            return false;
        }

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

        true
    }
}

/// Revenue expectation for an account
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Revenue {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub account_id: Uuid,
    pub amount: Decimal,
    pub start_date: NaiveDate,
    pub end_date: Option<NaiveDate>,
    pub wave_service_id: Option<String>,
}

impl Revenue {
    /// Check if revenue is active on a given date
    pub fn is_active_on(&self, date: NaiveDate) -> bool {
        if date < self.start_date {
            return false;
        }

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

        true
    }
}

/// Customer invoice
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Invoice {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub customer_id: Uuid,
    pub start_date: NaiveDate,
    pub end_date: NaiveDate,
    pub status: InvoiceStatus,
    pub date_paid: Option<NaiveDate>,
    pub payment_type: Option<PaymentType>,
    pub wave_invoice_id: Option<String>,
}

/// Many-to-many: Invoice to projects (join table with amount snapshot)
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct InvoiceProject {
    pub id: Uuid,
    pub invoice_id: Uuid,
    pub project_id: Uuid,
    pub amount: Decimal,
    pub created_at: DateTime<Utc>,
}

/// Many-to-many: Invoice to revenues (join table with amount snapshot)
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct InvoiceRevenue {
    pub id: Uuid,
    pub invoice_id: Uuid,
    pub revenue_id: Uuid,
    pub amount: Decimal,
    pub created_at: DateTime<Utc>,
}
