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

#[derive(Debug, Clone, Serialize, Deserialize, FromRow, ToSchema)]
pub struct Settings {
    pub id: Uuid,
    pub user_id: Uuid,
    pub ocr_language: String,
    pub preferred_languages: Vec<String>,
    pub primary_language: String,
    pub auto_detect_language_combination: bool,
    pub concurrent_ocr_jobs: i32,
    pub ocr_timeout_seconds: i32,
    pub max_file_size_mb: i32,
    pub allowed_file_types: Vec<String>,
    pub auto_rotate_images: bool,
    pub enable_image_preprocessing: bool,
    pub search_results_per_page: i32,
    pub search_snippet_length: i32,
    pub fuzzy_search_threshold: f32,
    pub retention_days: Option<i32>,
    pub enable_auto_cleanup: bool,
    pub enable_compression: bool,
    pub memory_limit_mb: i32,
    pub cpu_priority: String,
    pub enable_background_ocr: bool,
    pub ocr_page_segmentation_mode: i32,
    pub ocr_engine_mode: i32,
    pub ocr_min_confidence: f32,
    pub ocr_dpi: i32,
    pub ocr_enhance_contrast: bool,
    pub ocr_remove_noise: bool,
    pub ocr_detect_orientation: bool,
    pub ocr_whitelist_chars: Option<String>,
    pub ocr_blacklist_chars: Option<String>,
    pub ocr_brightness_boost: f32,
    pub ocr_contrast_multiplier: f32,
    pub ocr_noise_reduction_level: i32,
    pub ocr_sharpening_strength: f32,
    pub ocr_morphological_operations: bool,
    pub ocr_adaptive_threshold_window_size: i32,
    pub ocr_histogram_equalization: bool,
    pub ocr_upscale_factor: f32,
    pub ocr_max_image_width: i32,
    pub ocr_max_image_height: i32,
    pub save_processed_images: bool,
    pub ocr_quality_threshold_brightness: f32,
    pub ocr_quality_threshold_contrast: f32,
    pub ocr_quality_threshold_noise: f32,
    pub ocr_quality_threshold_sharpness: f32,
    pub ocr_skip_enhancement: bool,
    pub webdav_enabled: bool,
    pub webdav_server_url: Option<String>,
    pub webdav_username: Option<String>,
    pub webdav_password: Option<String>,
    pub webdav_watch_folders: Vec<String>,
    pub webdav_file_extensions: Vec<String>,
    pub webdav_auto_sync: bool,
    pub webdav_sync_interval_minutes: i32,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct SettingsResponse {
    pub ocr_language: String,
    pub preferred_languages: Vec<String>,
    pub primary_language: String,
    pub auto_detect_language_combination: bool,
    pub concurrent_ocr_jobs: i32,
    pub ocr_timeout_seconds: i32,
    pub max_file_size_mb: i32,
    pub allowed_file_types: Vec<String>,
    pub auto_rotate_images: bool,
    pub enable_image_preprocessing: bool,
    pub search_results_per_page: i32,
    pub search_snippet_length: i32,
    pub fuzzy_search_threshold: f32,
    pub retention_days: Option<i32>,
    pub enable_auto_cleanup: bool,
    pub enable_compression: bool,
    pub memory_limit_mb: i32,
    pub cpu_priority: String,
    pub enable_background_ocr: bool,
    pub ocr_page_segmentation_mode: i32,
    pub ocr_engine_mode: i32,
    pub ocr_min_confidence: f32,
    pub ocr_dpi: i32,
    pub ocr_enhance_contrast: bool,
    pub ocr_remove_noise: bool,
    pub ocr_detect_orientation: bool,
    pub ocr_whitelist_chars: Option<String>,
    pub ocr_blacklist_chars: Option<String>,
    pub ocr_brightness_boost: f32,
    pub ocr_contrast_multiplier: f32,
    pub ocr_noise_reduction_level: i32,
    pub ocr_sharpening_strength: f32,
    pub ocr_morphological_operations: bool,
    pub ocr_adaptive_threshold_window_size: i32,
    pub ocr_histogram_equalization: bool,
    pub ocr_upscale_factor: f32,
    pub ocr_max_image_width: i32,
    pub ocr_max_image_height: i32,
    pub save_processed_images: bool,
    pub ocr_quality_threshold_brightness: f32,
    pub ocr_quality_threshold_contrast: f32,
    pub ocr_quality_threshold_noise: f32,
    pub ocr_quality_threshold_sharpness: f32,
    pub ocr_skip_enhancement: bool,
    pub webdav_enabled: bool,
    pub webdav_server_url: Option<String>,
    pub webdav_username: Option<String>,
    pub webdav_password: Option<String>,
    pub webdav_watch_folders: Vec<String>,
    pub webdav_file_extensions: Vec<String>,
    pub webdav_auto_sync: bool,
    pub webdav_sync_interval_minutes: i32,
}

#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UpdateSettings {
    pub ocr_language: Option<String>,
    pub preferred_languages: Option<Vec<String>>,
    pub primary_language: Option<String>,
    pub auto_detect_language_combination: Option<bool>,
    pub concurrent_ocr_jobs: Option<i32>,
    pub ocr_timeout_seconds: Option<i32>,
    pub max_file_size_mb: Option<i32>,
    pub allowed_file_types: Option<Vec<String>>,
    pub auto_rotate_images: Option<bool>,
    pub enable_image_preprocessing: Option<bool>,
    pub search_results_per_page: Option<i32>,
    pub search_snippet_length: Option<i32>,
    pub fuzzy_search_threshold: Option<f32>,
    pub retention_days: Option<Option<i32>>,
    pub enable_auto_cleanup: Option<bool>,
    pub enable_compression: Option<bool>,
    pub memory_limit_mb: Option<i32>,
    pub cpu_priority: Option<String>,
    pub enable_background_ocr: Option<bool>,
    pub ocr_page_segmentation_mode: Option<i32>,
    pub ocr_engine_mode: Option<i32>,
    pub ocr_min_confidence: Option<f32>,
    pub ocr_dpi: Option<i32>,
    pub ocr_enhance_contrast: Option<bool>,
    pub ocr_remove_noise: Option<bool>,
    pub ocr_detect_orientation: Option<bool>,
    pub ocr_whitelist_chars: Option<Option<String>>,
    pub ocr_blacklist_chars: Option<Option<String>>,
    pub ocr_brightness_boost: Option<f32>,
    pub ocr_contrast_multiplier: Option<f32>,
    pub ocr_noise_reduction_level: Option<i32>,
    pub ocr_sharpening_strength: Option<f32>,
    pub ocr_morphological_operations: Option<bool>,
    pub ocr_adaptive_threshold_window_size: Option<i32>,
    pub ocr_histogram_equalization: Option<bool>,
    pub ocr_upscale_factor: Option<f32>,
    pub ocr_max_image_width: Option<i32>,
    pub ocr_max_image_height: Option<i32>,
    pub save_processed_images: Option<bool>,
    pub ocr_quality_threshold_brightness: Option<f32>,
    pub ocr_quality_threshold_contrast: Option<f32>,
    pub ocr_quality_threshold_noise: Option<f32>,
    pub ocr_quality_threshold_sharpness: Option<f32>,
    pub ocr_skip_enhancement: Option<bool>,
    pub webdav_enabled: Option<bool>,
    pub webdav_server_url: Option<Option<String>>,
    pub webdav_username: Option<Option<String>>,
    pub webdav_password: Option<Option<String>>,
    pub webdav_watch_folders: Option<Vec<String>>,
    pub webdav_file_extensions: Option<Vec<String>>,
    pub webdav_auto_sync: Option<bool>,
    pub webdav_sync_interval_minutes: Option<i32>,
}

impl From<Settings> for SettingsResponse {
    fn from(settings: Settings) -> Self {
        Self {
            ocr_language: settings.ocr_language,
            preferred_languages: settings.preferred_languages,
            primary_language: settings.primary_language,
            auto_detect_language_combination: settings.auto_detect_language_combination,
            concurrent_ocr_jobs: settings.concurrent_ocr_jobs,
            ocr_timeout_seconds: settings.ocr_timeout_seconds,
            max_file_size_mb: settings.max_file_size_mb,
            allowed_file_types: settings.allowed_file_types,
            auto_rotate_images: settings.auto_rotate_images,
            enable_image_preprocessing: settings.enable_image_preprocessing,
            search_results_per_page: settings.search_results_per_page,
            search_snippet_length: settings.search_snippet_length,
            fuzzy_search_threshold: settings.fuzzy_search_threshold,
            retention_days: settings.retention_days,
            enable_auto_cleanup: settings.enable_auto_cleanup,
            enable_compression: settings.enable_compression,
            memory_limit_mb: settings.memory_limit_mb,
            cpu_priority: settings.cpu_priority,
            enable_background_ocr: settings.enable_background_ocr,
            ocr_page_segmentation_mode: settings.ocr_page_segmentation_mode,
            ocr_engine_mode: settings.ocr_engine_mode,
            ocr_min_confidence: settings.ocr_min_confidence,
            ocr_dpi: settings.ocr_dpi,
            ocr_enhance_contrast: settings.ocr_enhance_contrast,
            ocr_remove_noise: settings.ocr_remove_noise,
            ocr_detect_orientation: settings.ocr_detect_orientation,
            ocr_whitelist_chars: settings.ocr_whitelist_chars,
            ocr_blacklist_chars: settings.ocr_blacklist_chars,
            ocr_brightness_boost: settings.ocr_brightness_boost,
            ocr_contrast_multiplier: settings.ocr_contrast_multiplier,
            ocr_noise_reduction_level: settings.ocr_noise_reduction_level,
            ocr_sharpening_strength: settings.ocr_sharpening_strength,
            ocr_morphological_operations: settings.ocr_morphological_operations,
            ocr_adaptive_threshold_window_size: settings.ocr_adaptive_threshold_window_size,
            ocr_histogram_equalization: settings.ocr_histogram_equalization,
            ocr_upscale_factor: settings.ocr_upscale_factor,
            ocr_max_image_width: settings.ocr_max_image_width,
            ocr_max_image_height: settings.ocr_max_image_height,
            save_processed_images: settings.save_processed_images,
            ocr_quality_threshold_brightness: settings.ocr_quality_threshold_brightness,
            ocr_quality_threshold_contrast: settings.ocr_quality_threshold_contrast,
            ocr_quality_threshold_noise: settings.ocr_quality_threshold_noise,
            ocr_quality_threshold_sharpness: settings.ocr_quality_threshold_sharpness,
            ocr_skip_enhancement: settings.ocr_skip_enhancement,
            webdav_enabled: settings.webdav_enabled,
            webdav_server_url: settings.webdav_server_url,
            webdav_username: settings.webdav_username,
            webdav_password: settings.webdav_password,
            webdav_watch_folders: settings.webdav_watch_folders,
            webdav_file_extensions: settings.webdav_file_extensions,
            webdav_auto_sync: settings.webdav_auto_sync,
            webdav_sync_interval_minutes: settings.webdav_sync_interval_minutes,
        }
    }
}

impl UpdateSettings {
    /// Create an UpdateSettings that only updates language preferences
    pub fn language_update(
        preferred_languages: Vec<String>,
        primary_language: String,
        ocr_language: String,
    ) -> Self {
        Self {
            preferred_languages: Some(preferred_languages),
            primary_language: Some(primary_language),
            ocr_language: Some(ocr_language),
            auto_detect_language_combination: None,
            concurrent_ocr_jobs: None,
            ocr_timeout_seconds: None,
            max_file_size_mb: None,
            allowed_file_types: None,
            auto_rotate_images: None,
            enable_image_preprocessing: None,
            search_results_per_page: None,
            search_snippet_length: None,
            fuzzy_search_threshold: None,
            retention_days: None,
            enable_auto_cleanup: None,
            enable_compression: None,
            memory_limit_mb: None,
            cpu_priority: None,
            enable_background_ocr: None,
            ocr_page_segmentation_mode: None,
            ocr_engine_mode: None,
            ocr_min_confidence: None,
            ocr_dpi: None,
            ocr_enhance_contrast: None,
            ocr_remove_noise: None,
            ocr_detect_orientation: None,
            ocr_whitelist_chars: None,
            ocr_blacklist_chars: None,
            ocr_brightness_boost: None,
            ocr_contrast_multiplier: None,
            ocr_noise_reduction_level: None,
            ocr_sharpening_strength: None,
            ocr_morphological_operations: None,
            ocr_adaptive_threshold_window_size: None,
            ocr_histogram_equalization: None,
            ocr_upscale_factor: None,
            ocr_max_image_width: None,
            ocr_max_image_height: None,
            save_processed_images: None,
            ocr_quality_threshold_brightness: None,
            ocr_quality_threshold_contrast: None,
            ocr_quality_threshold_noise: None,
            ocr_quality_threshold_sharpness: None,
            ocr_skip_enhancement: None,
            webdav_enabled: None,
            webdav_server_url: None,
            webdav_username: None,
            webdav_password: None,
            webdav_watch_folders: None,
            webdav_file_extensions: None,
            webdav_auto_sync: None,
            webdav_sync_interval_minutes: None,
        }
    }
}

impl Default for Settings {
    fn default() -> Self {
        Self {
            id: Uuid::new_v4(),
            user_id: Uuid::nil(),
            ocr_language: "eng".to_string(),
            preferred_languages: vec!["eng".to_string()],
            primary_language: "eng".to_string(),
            auto_detect_language_combination: false,
            concurrent_ocr_jobs: 4,
            ocr_timeout_seconds: 300,
            max_file_size_mb: 50,
            allowed_file_types: vec![
                "pdf".to_string(),
                "png".to_string(),
                "jpg".to_string(),
                "jpeg".to_string(),
                "tiff".to_string(),
                "bmp".to_string(),
                "txt".to_string(),
            ],
            auto_rotate_images: true,
            enable_image_preprocessing: false,
            search_results_per_page: 25,
            search_snippet_length: 200,
            fuzzy_search_threshold: 0.8,
            retention_days: None,
            enable_auto_cleanup: false,
            enable_compression: false,
            memory_limit_mb: 512,
            cpu_priority: "normal".to_string(),
            enable_background_ocr: true,
            ocr_page_segmentation_mode: 3, // PSM_AUTO_OSD - Fully automatic page segmentation, but no OSD
            ocr_engine_mode: 3, // OEM_DEFAULT - Default, based on what is available
            ocr_min_confidence: 30.0, // Minimum confidence threshold (0-100)
            ocr_dpi: 300, // Optimal DPI for OCR
            ocr_enhance_contrast: true, // Enable contrast enhancement
            ocr_remove_noise: true, // Enable noise removal
            ocr_detect_orientation: true, // Enable orientation detection
            ocr_whitelist_chars: None, // No character whitelist by default
            ocr_blacklist_chars: None, // No character blacklist by default
            ocr_brightness_boost: 1.0, // Conservative brightness boost
            ocr_contrast_multiplier: 1.2, // Conservative contrast enhancement
            ocr_noise_reduction_level: 1, // Light noise reduction
            ocr_sharpening_strength: 0.5, // Light sharpening
            ocr_morphological_operations: false, // Conservative - no morphological ops by default
            ocr_adaptive_threshold_window_size: 15, // Small window for adaptive threshold
            ocr_histogram_equalization: false, // Conservative - no histogram equalization by default
            ocr_upscale_factor: 1.0, // No upscaling by default
            ocr_max_image_width: 3000, // Reasonable max width
            ocr_max_image_height: 3000, // Reasonable max height
            save_processed_images: false, // Conservative - don't save by default
            ocr_quality_threshold_brightness: 0.3, // Conservative threshold
            ocr_quality_threshold_contrast: 0.2, // Conservative threshold
            ocr_quality_threshold_noise: 0.7, // Conservative threshold
            ocr_quality_threshold_sharpness: 0.3, // Conservative threshold
            ocr_skip_enhancement: false, // Allow enhancement by default
            webdav_enabled: false,
            webdav_server_url: None,
            webdav_username: None,
            webdav_password: None,
            webdav_watch_folders: vec!["/Documents".to_string()],
            webdav_file_extensions: vec![
                "pdf".to_string(),
                "png".to_string(),
                "jpg".to_string(),
                "jpeg".to_string(),
                "tiff".to_string(),
                "bmp".to_string(),
                "txt".to_string(),
            ],
            webdav_auto_sync: false,
            webdav_sync_interval_minutes: 60,
            created_at: chrono::Utc::now(),
            updated_at: chrono::Utc::now(),
        }
    }
}