///|
/// Main CronExpr type and API.
/// This is the primary interface for users of the mooncron library.

///|
/// A parsed and validated cron expression.
pub struct CronExpr {
  fields : Array[CronField]
  expression : String
}

///|
/// Parse a cron expression string.
/// Returns a CronExpr or an error with details.
pub fn CronExpr::parse(raw : String) -> Result[CronExpr, CronError] {
  let result = parse_cron_expression(raw)
  match result {
    Ok(fields) => Ok({ fields, expression: raw })
    Err(err) => Err(err)
  }
}

///|
/// Check if the expression is syntactically valid.
pub fn CronExpr::is_valid(self : CronExpr) -> Bool {
  ignore(self)
  // If we constructed a CronExpr, it passed validation during parse
  true
}

///|
/// Check if a DateTime matches this cron expression.
pub fn CronExpr::matches(self : CronExpr, dt : DateTime) -> Bool {
  matches_time(self.fields, dt)
}

///|
/// Get the next execution time after the given reference time.
pub fn CronExpr::next_after(self : CronExpr, after : DateTime) -> DateTime? {
  next_after(self.fields, after)
}

///|
/// Get the next N execution times after the given reference time.
pub fn CronExpr::next_n(
  self : CronExpr,
  after : DateTime,
  n : Int,
) -> Array[DateTime] {
  next_n(self.fields, after, n)
}

///|
/// Get an English description of this cron expression.
pub fn CronExpr::describe_en(self : CronExpr) -> String {
  describe_en(self.fields)
}

///|
/// Get a Chinese description of this cron expression.
pub fn CronExpr::describe_cn(self : CronExpr) -> String {
  describe_cn(self.fields)
}

///|
/// Convert the expression to a human-readable string.
pub fn CronExpr::to_string(self : CronExpr) -> String {
  "CronExpr(" + self.expression + ")"
}

///|
/// Get the original expression string.
pub fn CronExpr::raw(self : CronExpr) -> String {
  self.expression
}

///|
/// Validate a cron expression string without constructing a CronExpr.
pub fn validate(raw : String) -> Result[Unit, CronError] {
  validate_expression(raw)
}