package trikita.talalarmo.ui;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.PopupMenu;

import static trikita.anvil.DSL.*;

import trikita.anvil.Anvil;
import trikita.jedux.Action;
import trikita.talalarmo.Actions;
import trikita.talalarmo.App;
import trikita.talalarmo.MainActivity;
import trikita.talalarmo.R;

public class AlarmLayout {
    public static void view() {
        backgroundColor(Theme.get(App.getState().settings().theme()).backgroundColor);
        linearLayout(() -> {
            orientation(LinearLayout.VERTICAL);
            header();
            frameLayout(() -> {
                size(FILL, 0);
                weight(1f);
                if (App.getState().alarm().on()) {
                    alarmOnLayout();
                } else {
                    alarmOffLayout();
                }
            });
            bottomBar();
        });
    }

    private static void header() {
        linearLayout(() -> {
            size(FILL, WRAP);
            gravity(CENTER_VERTICAL);
            Theme.materialIcon(() -> {
                textColor(Theme.get(App.getState().settings().theme()).secondaryTextColor);
                textSize(dip(32));
                padding(dip(15));
                text("\ue855"); // "alarm" icon
            });
            textView(() -> {
                size(WRAP, WRAP);
                weight(1f);
                typeface("fonts/Roboto-Light.ttf");
                textSize(dip(20));
                textColor(Theme.get(App.getState().settings().theme()).primaryTextColor);
                text(R.string.app_name);
            });
        });
    }

    private static void alarmOffLayout() {
        textView(() -> {
            size(FILL, FILL);
            padding(dip(20));
            gravity(LEFT | CENTER_VERTICAL);
            typeface("fonts/Roboto-Light.ttf");
            allCaps(true);
            textSize(dip(32));
            textColor(Theme.get(App.getState().settings().theme()).primaryTextColor);
            text(R.string.tv_start_alarm_text);
            onClick(v -> App.dispatch(new Action<>(Actions.Alarm.ON)));
        });
    }

    private static void alarmOnLayout() {
        frameLayout(() -> {
            size(FILL, FILL);
            // On tablets leave some margin around the clock view to avoid gigantic circles
            if ((Anvil.currentView().getResources().getConfiguration().screenLayout &
                    Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE) {
                margin(dip(48));
            } else {
                margin(dip(8));
            }
            int w = Anvil.currentView().getWidth();
            int h = Anvil.currentView().getHeight();
            if (h == 0 || w == 0) {
                Anvil.currentView().post(Anvil::render);
            }

            int hourCircleSize;
            int minuteCircleSize;
            int amPmWidth;

            if (isPortrait()) {
                hourCircleSize = (int) (w * 1.1f * 0.62f);
                minuteCircleSize = (int) (hourCircleSize * 0.62f);
                amPmWidth = (int) (hourCircleSize * 0.62f * 0.62f);
            } else {
                hourCircleSize = (int) (h);
                minuteCircleSize = (int) (hourCircleSize * 0.62f);
                amPmWidth = (int) (hourCircleSize * 0.62f * 0.62f);
            }

            frameLayout(() -> {
                size(hourCircleSize, hourCircleSize);
                if (isPortrait()) {
                    x(w / 2 - hourCircleSize * 0.21f - hourCircleSize / 2);
                    y(h / 2 + hourCircleSize * 0.19f - hourCircleSize / 2);
                } else {
                    x(w / 2 - hourCircleSize * 0.38f - hourCircleSize / 2);
                    y(h / 2 + hourCircleSize * 0.00f - hourCircleSize / 2);
                }
                gravity(CENTER);
                v(ClockView.class, () -> {
                    size(FILL, FILL);
                    progress(App.getState().alarm().hours());
                    max(12);
                    onSeekBarChange((v, progress, fromUser) -> {
                        if (fromUser) {
                            App.dispatch(new Action<>(Actions.Alarm.SET_HOUR, progress));
                        }
                    });
                    Anvil.currentView().invalidate();
                });
                textView(() -> {
                    size(WRAP, WRAP);
                    int hours = App.getState().alarm().hours();
                    if (DateFormat.is24HourFormat(Anvil.currentView().getContext())) {
                        text(String.format("%02d", hours + (App.getState().alarm().am() ? 0 : 12)));
                    } else {
                        if (hours == 0) {
                            text("12");
                        } else {
                            text(String.format("%02d", hours));
                        }
                    }
                    layoutGravity(CENTER);
                    typeface("fonts/Roboto-Light.ttf");
                    textSize(hourCircleSize * 0.3f);
                    textColor(Theme.get(App.getState().settings().theme()).primaryColor);
                });
            });

            frameLayout(() -> {
                size(minuteCircleSize, minuteCircleSize);
                if (isPortrait()) {
                    x(w / 2 - hourCircleSize * 0.25f + minuteCircleSize / 2);
                    y(h / 2 + hourCircleSize * 0.05f - hourCircleSize / 2 - minuteCircleSize / 2);
                } else {
                    x(w / 2 - hourCircleSize * 0.25f + minuteCircleSize / 2);
                    y(h / 2 + hourCircleSize * 0.28f - hourCircleSize / 2 - minuteCircleSize / 2);
                }
                gravity(CENTER);
                v(ClockView.class, () -> {
                    size(FILL, FILL);
                    progress(App.getState().alarm().minutes());
                    max(60);
                    onSeekBarChange((v, progress, fromUser) -> {
                        if (fromUser) {
                            if (App.getState().settings().snap()) {
                                progress = (int) (Math.round(progress / 5.0) * 5) % 60;
                            }
                            App.dispatch(new Action<>(Actions.Alarm.SET_MINUTE, progress));
                        }
                    });
                    Anvil.currentView().invalidate();
                });
                textView(() -> {
                    size(WRAP, WRAP);
                    text(String.format("%02d", App.getState().alarm().minutes()));
                    layoutGravity(CENTER);
                    typeface("fonts/Roboto-Light.ttf");
                    textSize(minuteCircleSize * 0.3f);
                    textColor(Theme.get(App.getState().settings().theme()).primaryColor);
                });
            });

            v(AmPmSwitch.class, () -> {
                size(amPmWidth, (int) (amPmWidth / 1.5f));
                if (isPortrait()) {
                    x(w / 2 - hourCircleSize * 0.21f - amPmWidth * 3 / 4);
                    y(h / 2 + hourCircleSize * 0.05f - hourCircleSize / 2 - amPmWidth / 1.5f / 2);
                } else {
                    x(w / 2 - hourCircleSize * 0.25f + minuteCircleSize - amPmWidth / 2);
                    y(h / 2 + hourCircleSize * 0.25f - amPmWidth / 1.5f / 2);
                }
                checked(App.getState().alarm().am());
                onCheckedChange((CompoundButton buttonView, boolean isChecked) -> {
                    App.dispatch(new Action<>(Actions.Alarm.SET_AM_PM, isChecked));
                });
            });
        });
    }

    private static void bottomBar() {
        linearLayout(() -> {
            size(FILL, dip(62));
            backgroundColor(Theme.get(App.getState().settings().theme()).backgroundTranslucentColor);

            Theme.materialIcon(() -> {
                text("\ue857"); // ALARM OFF
                textSize(dip(32));
                textColor(Theme.get(App.getState().settings().theme()).secondaryTextColor);
                padding(dip(15));
                visibility(App.getState().alarm().on());
                onClick(v -> App.dispatch(new Action<>(Actions.Alarm.OFF)));
            });

            textView(() -> {
                size(0, FILL);
                weight(1f);
                margin(dip(10), 0);
                typeface("fonts/Roboto-Light.ttf");
                textSize(dip(16));
                textColor(Theme.get(App.getState().settings().theme()).primaryTextColor);
                gravity(CENTER | CENTER_VERTICAL);
                text(formatAlarmTime(Anvil.currentView().getContext()));
            });

            Theme.materialIcon(() -> {
                text("\ue5d4"); // "more vert"
                textSize(dip(32));
                textColor(Theme.get(App.getState().settings().theme()).secondaryTextColor);
                padding(dip(15));
                onClick(AlarmLayout::showSettingsMenu);
            });
        });
    }

    private static String formatAlarmTime(Context c) {
        if (!App.getState().alarm().on()) {
            return "";
        }
        long t = App.getState().alarm().nextAlarm().getTimeInMillis() - System.currentTimeMillis() - 1;
        t = t / 60 / 1000;
        int m = (int) (t % 60);
        int h = (int) (t / 60);

        String minSeq = (m == 0) ? "" :
                (m == 1) ? c.getString(R.string.minute) :
                        c.getString(R.string.minutes, Long.toString(m));

        String hourSeq = (h == 0) ? "" :
                (h == 1) ? c.getString(R.string.hour) :
                        c.getString(R.string.hours, Long.toString(h));

        int index = ((h > 0) ? 1 : 0) | ((m > 0) ? 2 : 0);

        String[] formats = c.getResources().getStringArray(R.array.alarm_set);
        return String.format(formats[index], hourSeq, minSeq);
    }

    private static void showSettingsMenu(View v) {
        PopupMenu menu = new PopupMenu(v.getContext(), v);
        menu.getMenuInflater().inflate(R.menu.overflow_popup, menu.getMenu());
        menu.setOnMenuItemClickListener(item -> {
            if (item.getItemId() == R.id.menu_settings) {
                ((MainActivity) v.getContext()).openSettings();
            } else if (item.getItemId() == R.id.menu_feedback) {
                Context c = v.getContext();
                Intent intent = new Intent(Intent.ACTION_SENDTO,
                        Uri.fromParts("mailto", "[email protected]", null));
                intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback about Talalarmo");
                v.getContext().startActivity(Intent.createChooser(intent, c.getString(R.string.leave_feedback)));
            }
            return true;
        });
        menu.show();
    }
}