// Copyright 2025 The Grim Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use eframe::epaint::RectShape;
use egui::{Align, CursorIcon, Layout, RichText, Sense, StrokeKind, UiBuilder};

use crate::AppConfig;
use crate::gui::Colors;
use crate::gui::platform::PlatformCallbacks;
use crate::gui::views::types::ContentContainer;
use crate::gui::views::{Modal, View};

/// User interface settings content.
pub struct InterfaceSettingsContent {
	/// Current locale.
	locale: String,
}

impl ContentContainer for InterfaceSettingsContent {
	fn modal_ids(&self) -> Vec<&'static str> {
		vec![]
	}

	fn modal_ui(&mut self, _: &mut egui::Ui, _: &Modal, _: &dyn PlatformCallbacks) {}

	fn container_ui(&mut self, ui: &mut egui::Ui, _: &dyn PlatformCallbacks) {
		ui.add_space(5.0);

		// Draw theme selection.
		ui.vertical_centered(|ui| {
			ui.label(RichText::new(t!("theme")).size(16.0).color(Colors::gray()));
		});

		let saved_use_dark = AppConfig::dark_theme().unwrap_or(false);
		let mut selected_use_dark = saved_use_dark;

		ui.add_space(8.0);
		ui.columns(2, |columns| {
			columns[0].vertical_centered(|ui| {
				View::radio_value(ui, &mut selected_use_dark, false, t!("light"));
			});
			columns[1].vertical_centered(|ui| {
				View::radio_value(ui, &mut selected_use_dark, true, t!("dark"));
			})
		});
		ui.add_space(14.0);
		if saved_use_dark != selected_use_dark {
			AppConfig::set_dark_theme(selected_use_dark);
			crate::setup_visuals(ui.ctx());
		}

		// Draw language selection.
		let locales = rust_i18n::available_locales!();
		for (index, locale) in locales.iter().enumerate() {
			self.language_item_ui(locale, ui, index, locales.len());
		}
		ui.add_space(4.0);
	}
}

impl Default for InterfaceSettingsContent {
	fn default() -> Self {
		let locale = if let Some(lang) = AppConfig::locale() {
			lang
		} else {
			rust_i18n::locale().to_string()
		};
		Self { locale }
	}
}

impl InterfaceSettingsContent {
	/// Draw language selection item content.
	fn language_item_ui(&mut self, locale: &str, ui: &mut egui::Ui, index: usize, len: usize) {
		let is_current = self.locale == locale;
		// Draw round background.
		let mut rect = ui.available_rect_before_wrap();
		rect.set_height(50.0);
		let r = View::item_rounding(index, len, false);
		let bg = if is_current {
			Colors::fill()
		} else {
			Colors::fill_lite()
		};
		let mut bg_shape = RectShape::new(rect, r, bg, View::item_stroke(), StrokeKind::Outside);
		let bg_idx = ui.painter().add(bg_shape.clone());

		let res = ui
			.scope_builder(
				UiBuilder::new()
					.sense(Sense::click())
					.layout(Layout::right_to_left(Align::Center))
					.max_rect(rect),
				|ui| {
					if is_current {
						View::selected_item_check(ui);
					}
					let layout_size = ui.available_size();
					ui.allocate_ui_with_layout(
						layout_size,
						Layout::left_to_right(Align::Center),
						|ui| {
							ui.add_space(12.0);
							ui.vertical(|ui| {
								// Draw language name.
								ui.add_space(12.0);
								let color = if is_current {
									Colors::title(false)
								} else {
									Colors::gray()
								};
								ui.label(
									RichText::new(t!("lang_name", locale = locale))
										.size(17.0)
										.color(color),
								);
								ui.add_space(14.0);
							});
						},
					);
				},
			)
			.response;
		let clicked = res.clicked() || res.long_touched();
		// Setup background and cursor.
		if res.hovered() && !is_current {
			res.on_hover_cursor(CursorIcon::PointingHand);
			bg_shape.fill = Colors::fill();
		}
		ui.painter().set(bg_idx, bg_shape);
		// Handle clicks on layout.
		if clicked && !is_current {
			rust_i18n::set_locale(locale);
			AppConfig::save_locale(locale);
			self.locale = locale.to_string();
		}
	}
}
