use crate::error::{ApiError, Result};
use regex::Regex;

#[derive(Clone)]
pub struct ValidationBuilder {
    errors: Vec<String>,
}

impl ValidationBuilder {
    pub fn new() -> Self {
        Self { errors: Vec::new() }
    }
    
    pub fn require(mut self, value: &str, field_name: &str) -> Self {
        if value.trim().is_empty() {
            self.errors.push(format!("{} is required", field_name));
        }
        self
    }
    
    
    pub fn validate_email(mut self, email: &str) -> Self {
        let email_regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
        if !email_regex.is_match(email) {
            self.errors.push("Invalid email format".to_string());
        }
        self
    }
    
    pub fn validate_length(mut self, value: &str, field_name: &str, min: usize, max: usize) -> Self {
        let len = value.trim().len();
        if len < min {
            self.errors.push(format!("{} must be at least {} characters", field_name, min));
        } else if len > max {
            self.errors.push(format!("{} must be at most {} characters", field_name, max));
        }
        self
    }
    
    pub fn validate_url(mut self, url: &str, field_name: &str) -> Self {
        if !url.is_empty() && !url.starts_with("http://") && !url.starts_with("https://") {
            self.errors.push(format!("{} must be a valid URL", field_name));
        }
        self
    }
    
    pub fn validate_phone(mut self, phone: &str, field_name: &str) -> Self {
        let phone_regex = Regex::new(r"^\+?[\d\s\-\(\)]+$").unwrap();
        if !phone.is_empty() && !phone_regex.is_match(phone) {
            self.errors.push(format!("{} must be a valid phone number", field_name));
        }
        self
    }
    
    pub fn validate_timezone(mut self, timezone: &str) -> Self {
        if chrono_tz::Tz::from_str(timezone).is_err() {
            self.errors.push(format!("Invalid timezone: {}", timezone));
        }
        self
    }
    
    
    pub fn build(self) -> Result<()> {
        if self.errors.is_empty() {
            Ok(())
        } else {
            Err(ApiError::ValidationError(self.errors.join(", ")))
        }
    }
    
}

use std::str::FromStr;

pub fn validate_recurring_type(recurring_type: &Option<String>) -> Result<()> {
    if let Some(rt) = recurring_type {
        match rt.as_str() {
            "none" | "daily" | "weekly" | "biweekly" | "monthly" | "first_tuesday" | "2nd/3rd Saturday Monthly" | "2nd_3rd_saturday_monthly" => Ok(()),
            _ => Err(ApiError::ValidationError("Invalid recurring type. Must be one of: none, daily, weekly, biweekly, monthly, first_tuesday, 2nd_3rd_saturday_monthly".to_string())),
        }
    } else {
        Ok(())
    }
}

pub fn get_valid_recurring_types() -> Vec<&'static str> {
    vec!["none", "daily", "weekly", "biweekly", "monthly", "first_tuesday", "2nd_3rd_saturday_monthly"]
}

/// Convert URL-friendly recurring type to database format
pub fn normalize_recurring_type(recurring_type: &str) -> String {
    match recurring_type {
        "2nd_3rd_saturday_monthly" => "2nd/3rd Saturday Monthly".to_string(),
        _ => recurring_type.to_string(),
    }
}
