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

use super::{BaseFields, WorkStatus};

/// Recurring cleaning service at an account address
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Service {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub account_id: Uuid,
    pub account_address_id: Uuid,
    pub date: NaiveDate,
    pub status: WorkStatus,
    pub notes: Option<String>,
    pub calendar_event_id: Option<String>,
}

/// Team member assignment to a service (many-to-many join table)
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ServiceTeamMember {
    pub id: Uuid,
    pub service_id: Uuid,
    pub team_profile_id: Uuid,
    pub created_at: DateTime<Utc>,
}

/// Recurring service schedule for an account address
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Schedule {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub account_address_id: Uuid,
    pub name: Option<String>,
    pub monday: bool,
    pub tuesday: bool,
    pub wednesday: bool,
    pub thursday: bool,
    pub friday: bool,
    pub saturday: bool,
    pub sunday: bool,
    pub weekend_service: bool,
    pub schedule_exception: Option<String>,
    pub start_date: Option<NaiveDate>,
    pub end_date: Option<NaiveDate>,
}

impl Schedule {
    /// Check if service is scheduled for a given weekday (0=Monday, 6=Sunday)
    pub fn is_scheduled_for_weekday(&self, weekday: u32) -> bool {
        if self.weekend_service {
            return weekday >= 5; // Saturday or Sunday
        }

        match weekday {
            0 => self.monday,
            1 => self.tuesday,
            2 => self.wednesday,
            3 => self.thursday,
            4 => self.friday,
            5 => self.saturday,
            6 => self.sunday,
            _ => false,
        }
    }

    /// Check if a service should be generated for a given weekday
    /// Returns (should_generate, optional_note)
    ///
    /// Logic mirrors Django backend:
    /// - Mon-Thu (0-3): Use individual day flags
    /// - Friday (4): If weekend_service, generate with note; otherwise use friday flag
    /// - Sat-Sun (5-6): If weekend_service, skip (Friday covers weekend); otherwise use day flags
    pub fn should_generate_for_weekday(&self, weekday: u32) -> (bool, Option<&'static str>) {
        match weekday {
            // Mon-Thu: always use individual day flags
            0 => (self.monday, None),
            1 => (self.tuesday, None),
            2 => (self.wednesday, None),
            3 => (self.thursday, None),
            // Friday: weekend_service takes precedence, otherwise use friday flag
            4 => {
                if self.weekend_service {
                    (true, Some("Weekend service window (Fri-Sun)"))
                } else {
                    (self.friday, None)
                }
            }
            // Sat-Sun: only use day flags if weekend_service is OFF
            5 => {
                if self.weekend_service {
                    (false, None)
                } else {
                    (self.saturday, None)
                }
            }
            6 => {
                if self.weekend_service {
                    (false, None)
                } else {
                    (self.sunday, None)
                }
            }
            _ => (false, None),
        }
    }

    /// Check if schedule is active for a given date
    pub fn is_active_on(&self, date: NaiveDate) -> bool {
        if let Some(start) = self.start_date {
            if date < start {
                return false;
            }
        }
        if let Some(end) = self.end_date {
            if date > end {
                return false;
            }
        }
        true
    }
}
