package com.castlabs.sdk.subtitle_styles;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;

import androidx.annotation.NonNull;

import com.castlabs.sdk.subtitles_styles.R;
import com.castlabs.subtitles.presentation.SubtitleFonts;
import com.castlabs.subtitles.presentation.SubtitlesStyle;
import com.castlabs.logutils.Log;

public class StyleBuilder {
	private static final String TAG = "StyleBuilder";
	private final Context context;
	private final SharedPreferences preferences;
	private final boolean isRemoteStyle;

	public StyleBuilder(Context context, SharedPreferences preferences, boolean isRemoteStyle) {
		this.context = context;
		this.preferences = preferences;
		this.isRemoteStyle = isRemoteStyle;
	}

	public StyleBuilder(Context context, SharedPreferences preferences) {
		this(context, preferences, false);  // Default to local style
	}

	public SubtitlesStyle createSubtitleStyle(){
		SubtitlesStyle.Builder builder = SubtitlesStyle.Builder.create(context, false);

		//noinspection WrongConstant
		builder.typeface(SubtitleFonts.get(readInt(R.string.prefs_subtitle_font_key, 0), context));
		builder.fontScale(readFloat(R.string.prefs_subtitle_font_scale_key, 1f));
		Integer fontSize = readInt(R.string.prefs_subtitle_font_size_key, 0);
		builder.displayAlign(readInt(R.string.prefs_subtitle_display_align_key, SubtitlesStyle.DEFAULT_DISPLAY_ALIGN));
		builder.textAlign(readInt(R.string.prefs_subtitle_text_align_key, SubtitlesStyle.DEFAULT_TEXT_ALIGN));
		builder.fontSize(fontSize, fontSize != 0);
		Integer color = color(R.string.prefs_subtitle_foreground_color_key);
		if (color != null) {
			builder.foregroundColor(color, true);
		}
		if (color != null && Color.alpha(color) > 0) {
			// only apply opacity if a color was selected that is not fully transparent
			builder.foregroundOpacity(readFloat(R.string.prefs_subtitle_text_opacity_key, 1));
		}
		int edgeType = readInt(R.string.prefs_subtitle_edge_type_key, SubtitlesStyle.DEFAULT_EDGE_TYPE);
		//noinspection WrongConstant
		builder.edgeType(edgeType, edgeType != SubtitlesStyle.DEFAULT_EDGE_TYPE);
		color = color(R.string.prefs_subtitle_edge_color_key);
		if (color != null) {
			builder.edgeColor(color, true);
		}
		int thickness = readInt(R.string.prefs_subtitle_edge_thickness_key, 0);
		builder.edgeThickness(thickness, thickness != 0);

		int radius = readInt(R.string.prefs_subtitle_edge_blur_radius_key, 0);
		builder.edgeBlurRadius(radius, radius != 0);

		color = color(R.string.prefs_subtitle_background_color_key);
		if (color != null) {
			builder.backgroundColor(color, true);
		}
		if (color != null && Color.alpha(color) > 0) {
			// only apply opacity if a color was selected that is not fully transparent
			builder.backgroundOpacity(readFloat(R.string.prefs_subtitle_background_opacity_key, 1));
		}
		color = color(R.string.prefs_subtitle_window_color_key);
		if (color != null) {
			builder.windowColor(color, true);
		}
		if (color != null && Color.alpha(color) > 0) {
			// only apply opacity if a color was selected that is not fully transparent
			builder.windowOpacity(readFloat(R.string.prefs_subtitle_window_opacity_key, 1));
		}
		color = color(R.string.prefs_subtitle_region_color_key);
		if (color != null) {
			builder.regionColor(color, true);
		}
		if (color != null && Color.alpha(color) > 0) {
			// only apply opacity if a color was selected that is not fully transparent
			builder.regionOpacity(readFloat(R.string.prefs_subtitle_region_opacity_key, 1));
		}
		builder.drawBeyondVideoArea(preferences.getBoolean(key(R.string.prefs_subtitle_canvas_area_key), false));
		builder.topMargin(readInt(R.string.prefs_subtitle_top_margin_key, 0));
		builder.bottomMargin(readInt(R.string.prefs_subtitle_bottom_margin_key, 0));
		builder.leftMargin(readInt(R.string.prefs_subtitle_left_margin_key, 0));
		builder.rightMargin(readInt(R.string.prefs_subtitle_right_margin_key, 0));

		return builder.get();
	}

	private Integer color(int key){
		String value = preferences.getString(key(key), "Default");
		if (value.equals("Default")){
			return null;
		} else if (value.equals("0")){
			return Color.TRANSPARENT;
		}
		try {
			return Color.parseColor(value);
		} catch (IllegalArgumentException e) {
			Log.w(TAG, "Error parsing value: " + e.getMessage() + ", using default");
			return null;
		}
	}

	private float readFloat(int key, float defaultValue){
		return readFloat(key(key), defaultValue, preferences);
	}

	private int readInt(int key, int defaultValue){
		return readInt(key(key), defaultValue, preferences);
	}

	private String key(int id) {
		String baseKey = context.getResources().getString(id);
		return isRemoteStyle ? "remote_" + baseKey : baseKey;
	}

	public static float readFloat(@NonNull String key, float defaultValue, @NonNull SharedPreferences sharedPreferences){
		String value = sharedPreferences.getString(key, null);
		if (value == null){
			return defaultValue;
		}
		try {
			return Float.parseFloat(value);
		} catch (NumberFormatException e) {
			Log.w(TAG, "Error parsing value: " + e.getMessage() + ", using default = " + defaultValue);
			return defaultValue;
		}
	}

	public static int readInt(@NonNull String key, int defaultValue, @NonNull SharedPreferences sharedPreferences) {
		String value = sharedPreferences.getString(key, null);
		if (value == null){
			return defaultValue;
		}
		try {
			return Integer.parseInt(value);
		} catch (NumberFormatException e) {
			Log.w(TAG, "Error parsing value: " + e.getMessage() + ", using default = " + defaultValue);
			return defaultValue;
		}
	}

	public static SubtitlesStyle createLocalSubtitleStyle(Context context, SharedPreferences preferences) {
		return new StyleBuilder(context, preferences, false).createSubtitleStyle();
	}

	public static SubtitlesStyle createRemoteSubtitleStyle(Context context, SharedPreferences preferences) {
		return new StyleBuilder(context, preferences, true).createSubtitleStyle();
	}
}
