//! Common types and enums used across calendar components

use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Serialize};

// ==================== ENUMS AND COMMON TYPES ====================

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum EventStatus {
    Tentative,
    Confirmed,
    Cancelled,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum EventClass {
    Public,
    Private,
    Confidential,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TimeTransparency {
    Opaque,      // OPAQUE - time is not available
    Transparent, // TRANSPARENT - time is available
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TodoStatus {
    NeedsAction,
    Completed,
    InProcess,
    Cancelled,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AttendeeRole {
    Chair,
    ReqParticipant,
    OptParticipant,
    NonParticipant,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ParticipationStatus {
    NeedsAction,
    Accepted,
    Declined,
    Tentative,
    Delegated,
    Completed,
    InProcess,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AlarmAction {
    Audio,
    Display,
    Email,
    Procedure,
}

// ==================== STRUCTURED TYPES ====================

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CalendarUser {
    pub cal_address: String,           // Calendar user address (usually email)
    pub common_name: Option<String>,   // CN parameter - display name
    pub dir_entry_ref: Option<String>, // DIR parameter - directory entry
    pub sent_by: Option<String>,       // SENT-BY parameter
    pub language: Option<String>,      // LANGUAGE parameter
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Attendee {
    pub cal_address: String,                    // Calendar user address
    pub common_name: Option<String>,            // CN parameter
    pub role: Option<AttendeeRole>,             // ROLE parameter
    pub part_stat: Option<ParticipationStatus>, // PARTSTAT parameter
    pub rsvp: Option<bool>,                     // RSVP parameter
    pub cu_type: Option<String>, // CUTYPE parameter (INDIVIDUAL, GROUP, RESOURCE, ROOM, UNKNOWN)
    pub member: Vec<String>,     // MEMBER parameter
    pub delegated_to: Vec<String>, // DELEGATED-TO parameter
    pub delegated_from: Vec<String>, // DELEGATED-FROM parameter
    pub sent_by: Option<String>, // SENT-BY parameter
    pub dir_entry_ref: Option<String>, // DIR parameter
    pub language: Option<String>, // LANGUAGE parameter
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VAlarm {
    pub action: AlarmAction,         // Action (ACTION) - REQUIRED
    pub trigger: AlarmTrigger,       // Trigger (TRIGGER) - REQUIRED
    pub duration: Option<Duration>,  // Duration (DURATION)
    pub repeat: Option<u32>,         // Repeat count (REPEAT)
    pub description: Option<String>, // Description for DISPLAY/EMAIL
    pub summary: Option<String>,     // Summary for EMAIL
    pub attendees: Vec<Attendee>,    // Attendees for EMAIL
    pub attach: Vec<Attachment>,     // Attachments for AUDIO/EMAIL
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum AlarmTrigger {
    DateTime(DateTime<Utc>), // Absolute trigger time
    Duration(Duration),      // Duration relative to start/end
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Attachment {
    pub format_type: Option<String>,  // FMTTYPE parameter (MIME type)
    pub encoding: Option<String>,     // ENCODING parameter
    pub value: Option<String>,        // VALUE parameter (BINARY or URI)
    pub uri: Option<String>,          // URI reference
    pub binary_data: Option<Vec<u8>>, // Binary data (when ENCODING=BASE64)
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct GeographicPosition {
    pub latitude: f64,  // Latitude in decimal degrees
    pub longitude: f64, // Longitude in decimal degrees
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VTimeZone {
    pub tzid: String,                                // Time zone ID (TZID) - REQUIRED
    pub last_modified: Option<DateTime<Utc>>,        // Last modified (LAST-MODIFIED)
    pub tzurl: Option<String>,                       // Time zone URL (TZURL)
    pub standard_components: Vec<TimeZoneComponent>, // STANDARD components
    pub daylight_components: Vec<TimeZoneComponent>, // DAYLIGHT components
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TimeZoneComponent {
    pub dtstart: DateTime<Utc>,    // Start of this time zone definition
    pub tzoffset_to: String,       // UTC offset for this component
    pub tzoffset_from: String,     // UTC offset before this component
    pub rrule: Option<String>,     // Recurrence rule
    pub rdate: Vec<DateTime<Utc>>, // Recurrence dates
    pub tzname: Vec<String>,       // Time zone names
    pub comment: Vec<String>,      // Comments
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VJournal {
    // Required properties
    pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
    pub uid: String,            // Unique identifier (UID) - REQUIRED

    // Optional properties
    pub dtstart: Option<DateTime<Utc>>, // Start date-time (DTSTART)
    pub summary: Option<String>,        // Summary/title (SUMMARY)
    pub description: Option<String>,    // Description (DESCRIPTION)

    // Classification and status
    pub class: Option<EventClass>, // Classification (CLASS)
    pub status: Option<String>,    // Status (STATUS)

    // People and organization
    pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
    pub attendees: Vec<Attendee>,        // Attendees (ATTENDEE)

    // Categorization
    pub categories: Vec<String>, // Categories (CATEGORIES)

    // Versioning and modification
    pub sequence: Option<u32>,                // Sequence number (SEQUENCE)
    pub created: Option<DateTime<Utc>>,       // Creation time (CREATED)
    pub last_modified: Option<DateTime<Utc>>, // Last modified (LAST-MODIFIED)

    // Recurrence
    pub rrule: Option<String>,                // Recurrence rule (RRULE)
    pub rdate: Vec<DateTime<Utc>>,            // Recurrence dates (RDATE)
    pub exdate: Vec<DateTime<Utc>>,           // Exception dates (EXDATE)
    pub recurrence_id: Option<DateTime<Utc>>, // Recurrence ID (RECURRENCE-ID)

    // Attachments
    pub attachments: Vec<Attachment>, // Attachments (ATTACH)
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct VFreeBusy {
    // Required properties
    pub dtstamp: DateTime<Utc>, // Date-time stamp (DTSTAMP) - REQUIRED
    pub uid: String,            // Unique identifier (UID) - REQUIRED

    // Optional date-time properties
    pub dtstart: Option<DateTime<Utc>>, // Start date-time (DTSTART)
    pub dtend: Option<DateTime<Utc>>,   // End date-time (DTEND)

    // People
    pub organizer: Option<CalendarUser>, // Organizer (ORGANIZER)
    pub attendees: Vec<Attendee>,        // Attendees (ATTENDEE)

    // Free/busy time
    pub freebusy: Vec<FreeBusyTime>, // Free/busy time periods
    pub url: Option<String>,         // URL (URL)
    pub comment: Vec<String>,        // Comments (COMMENT)
    pub contact: Option<String>,     // Contact information (CONTACT)
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct FreeBusyTime {
    pub fb_type: FreeBusyType, // Free/busy type
    pub periods: Vec<Period>,  // Time periods
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum FreeBusyType {
    Free,
    Busy,
    BusyUnavailable,
    BusyTentative,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Period {
    pub start: DateTime<Utc>,       // Period start
    pub end: Option<DateTime<Utc>>, // Period end
    pub duration: Option<Duration>, // Period duration (alternative to end)
}
