/* Copyright 2014-2023 askanimus@gmail.com */

/* This File is part of "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).  If not, see <http://www.gnu.org/licenses/>.
 *
 * Diese Datei ist Teil von "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) ist Freie Software: Sie können es unter den Bedingungen
 * der GNU General Public License, wie von der Free Software Foundation,
 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) wird in der Hoffnung, dass es nützlich sein wird, aber
 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 * Siehe die GNU General Public License für weitere Details.
 *
 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 */
package askanimus.arbeitszeiterfassung2.setup;


import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;

import askanimus.betterpickers.numberpicker.NumberPickerBuilder;
import askanimus.betterpickers.numberpicker.NumberPickerDialogFragment;
import askanimus.betterpickers.timepicker.TimePickerBuilder;
import askanimus.betterpickers.timepicker.TimePickerDialogFragment;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;

import askanimus.arbeitszeiterfassung2.MinutenInterpretationDialog;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.Uhrzeit;

/**
 * A placeholder fragment containing a simple view.
 */
public class SettingsFragmentArbeitszeit extends Fragment implements View.OnClickListener,
        AdapterView.OnItemSelectedListener,
        SwitchCompat.OnCheckedChangeListener,
        NumberPickerDialogFragment.NumberPickerDialogHandlerV2,
        TimePickerDialogFragment.TimePickerDialogHandler{
    private Arbeitsplatz mArbeitsplatz;
    private Context mContext;

    private Spinner sModell;
    private TextView tSollzeit;
    private TextView wSollzeit;
    private LinearLayout bMonatstage;
    private TextView wMonatstage;
    private LinearLayout bArbeitfrei;
    private Spinner[] sWochentage;
    private TextView[] wWochentage;
    private SwitchCompat wBezPause;
    private TextView hBezPause;
    private boolean isInitAssist;

    /*
    * Neue Instanz anlegen
    */
    public static SettingsFragmentArbeitszeit newInstance(long arbeitsplatz, boolean isInitAssist) {
        Bundle argumente = new Bundle();
        argumente.putLong(ISettings.KEY_EDIT_JOB, arbeitsplatz);
        argumente.putBoolean(ISettings.ARG_IS_INITASSIST, isInitAssist);
        SettingsFragmentArbeitszeit fragment = new SettingsFragmentArbeitszeit();
        fragment.setArguments(argumente);
        return fragment;
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mContext = getContext();
        return inflater.inflate(R.layout.fragment_init_arbeitszeit, container, false);
    }


    @Override
    public void onResume() {
        super.onResume();
        ASettings.init(mContext, this::resume);
    }

    private void resume() {
        Bundle args = getArguments();
        View mView = getView();
        if (args != null && mView != null) {
            // den zu bearbeitenden Arbeitsplatz ermitteln
            mArbeitsplatz = ASettings.getArbeitsplatz(
                    args.getLong(ISettings.KEY_EDIT_JOB, 0)
            );
            isInitAssist = args.getBoolean(ISettings.ARG_IS_INITASSIST, false);
            if (mArbeitsplatz != null) {
                //Widgeds finden
                TextView tTitel = mView.findViewById(R.id.I_arbeitszeit_titel);
                sModell = mView.findViewById(R.id.I_spinner_modell);
                tSollzeit = mView.findViewById(R.id.I_titel_sollstunden);
                wSollzeit = mView.findViewById(R.id.I_wert_sollstunden);
                bMonatstage = mView.findViewById(R.id.I_box_monatstage);
                wMonatstage = mView.findViewById(R.id.I_wert_monatstage);
                bArbeitfrei = mView.findViewById(R.id.I_box_arbeitfrei);

                wBezPause = mView.findViewById(R.id.I_switch_pause_bez);
                hBezPause = mView.findViewById(R.id.I_hint_pause_bez);

                sWochentage = new Spinner[8];
                sWochentage[Calendar.MONDAY] = mView.findViewById(R.id.I_spinner_montag);
                sWochentage[Calendar.TUESDAY] = mView.findViewById(R.id.I_spinner_dienstag);
                sWochentage[Calendar.WEDNESDAY] = mView.findViewById(R.id.I_spinner_mittwoch);
                sWochentage[Calendar.THURSDAY] = mView.findViewById(R.id.I_spinner_donnerstag);
                sWochentage[Calendar.FRIDAY] = mView.findViewById(R.id.I_spinner_freitag);
                sWochentage[Calendar.SATURDAY] = mView.findViewById(R.id.I_spinner_samstag);
                sWochentage[Calendar.SUNDAY] = mView.findViewById(R.id.I_spinner_sonntag);

                wWochentage = new TextView[8];
                wWochentage[Calendar.MONDAY] = mView.findViewById(R.id.I_soll_montag);
                wWochentage[Calendar.TUESDAY] = mView.findViewById(R.id.I_soll_dienstag);
                wWochentage[Calendar.WEDNESDAY] = mView.findViewById(R.id.I_soll_mittwoch);
                wWochentage[Calendar.THURSDAY] = mView.findViewById(R.id.I_soll_donnerstag);
                wWochentage[Calendar.FRIDAY] = mView.findViewById(R.id.I_soll_freitag);
                wWochentage[Calendar.SATURDAY] = mView.findViewById(R.id.I_soll_samstag);
                wWochentage[Calendar.SUNDAY] = mView.findViewById(R.id.I_soll_sonntag);

                // Seitentitel ausblenden wenn es nicht der Initassistent ist
                if (!isInitAssist) {
                    tTitel.setVisibility(View.GONE);
                }

                // Farben setzen
                wBezPause.setThumbTintList(mArbeitsplatz.getFarbe_Thumb());
                wBezPause.setTrackTintList(mArbeitsplatz.getFarbe_Trak());

                // Handler registrieren
                wBezPause.setOnCheckedChangeListener(this);
                wSollzeit.setOnClickListener(this);
                wMonatstage.setOnClickListener(this);
                sModell.setOnItemSelectedListener(this);
                for (int i = 1; i <= 7; i++) {
                    sWochentage[i].setOnItemSelectedListener(this);
                    wWochentage[i].setOnClickListener(this);
                }

                // Werte vorbelegen
                wBezPause.setChecked(mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_PAUSE_BEZAHLT));
                updateView();
                updateTagesliste();
            }
        }
    }

    private void updateView(){
        hBezPause.setText(
                wBezPause.isChecked()
                        ? R.string.hint_on_pause_bezahlt
                        : R.string.hint_off_pause_bezahlt
        );
    }

    @Override
    public void onStop() {
        if(mArbeitsplatz != null) {
            mArbeitsplatz.schreibeJob();
        }
        super.onStop();
    }


    private void setWochenstunden(){
        // Anpassen der Wochenstunden wenn sich etwas an den Arbeitstagen geändert hat
        int mWocheNeu = 0;
        if(mArbeitsplatz.getModell() != Arbeitsplatz.Soll_Monat_pauschal){
            for (int i = 1; i <= 7; i++) {
                mWocheNeu += mArbeitsplatz.getSollstundenTag(i);
            }
            if(mWocheNeu != mArbeitsplatz.getSollstundenWoche()){
                mArbeitsplatz.setSollstundenWoche(mWocheNeu, false);
                wSollzeit.setText(
                        new Uhrzeit(mWocheNeu)
                                .getStundenString(
                                        false,
                                        mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL))
                );
            }
        }

    }


    private void setTageswerte() {
        // die Werte der einzelnen Tage an Hand
        // der Sollstunden, des Modells und der Anzahl Arbeitstage anpassen
        // die Woche auf Arbeitszeitmodell anpassen
        int mArbeitstag;
        for (int i = 1; i <= 7; i++) {
            mArbeitstag = Math.round(mArbeitsplatz.getArbeitstag(i)*2);
            if(mArbeitstag == 0) {
                mArbeitsplatz.setSollTag(i, 0);
            } else {
                if(mArbeitstag == 1)
                    mArbeitsplatz.setSollTag(i,  mArbeitsplatz.getSollstundenTagPauschal()/2);
                else
                    mArbeitsplatz.setSollTag(i,  mArbeitsplatz.getSollstundenTagPauschal());
            }
        }

        updateTagesliste();
    }

    private void updateTagesliste() {
        Uhrzeit mZeit = new Uhrzeit();

        sModell.setSelection(mArbeitsplatz.getModell());
        wSollzeit.setText(new Uhrzeit(mArbeitsplatz.getSollstundenWoche()).getStundenString(true, mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));

        if (mArbeitsplatz.getModell() == Arbeitsplatz.Soll_Woche_rollend) {
            bArbeitfrei.setVisibility(View.GONE);
            bMonatstage.setVisibility(View.GONE);
        } else {
            bArbeitfrei.setVisibility(View.VISIBLE);

            if (mArbeitsplatz.getModell() == Arbeitsplatz.Soll_Monat_pauschal) {
                tSollzeit.setText(R.string.soll_monat);
                bMonatstage.setVisibility(View.VISIBLE);
                wMonatstage.setText(ASettings.zahlenformat.format(mArbeitsplatz.getArbeitstage_Monat()));
            } else {
                tSollzeit.setText(R.string.soll_woche);
                bMonatstage.setVisibility(View.GONE);
            }

            for (int i = 1; i <= 7; i++) {
                sWochentage[i].setSelection(Math.round(mArbeitsplatz.getArbeitstag(i) * 2));
                mZeit.set(mArbeitsplatz.getSollstundenTag(i));
                wWochentage[i].setText(mZeit.getStundenString(true, mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
                wWochentage[i].setEnabled((mArbeitsplatz.getArbeitstag(i) > 0) );
            }

        }
    }

    @Override
    public void onClick(View v) {
        final FragmentManager fragmentManager = requireActivity().getSupportFragmentManager();
        int id = v.getId();
        if (id == R.id.I_wert_sollstunden) {
            NumberPickerBuilder mSollPicker = new NumberPickerBuilder()
                    .setFragmentManager(fragmentManager)
                    .setStyleResId(ASettings.themePicker)
                    .setPlusMinusVisibility(View.INVISIBLE)
                    .setDecimalVisibility(View.VISIBLE)
                    .setLabelText(getString(R.string.k_stunde))
                    .setTargetFragment(this)
                    .setReference(id);
            mSollPicker.show();
        } else if (id == R.id.I_wert_monatstage) {
            NumberPickerBuilder mMonatstagePicker = new NumberPickerBuilder()
                    .setFragmentManager(fragmentManager)
                    .setStyleResId(ASettings.themePicker)
                    .setPlusMinusVisibility(View.INVISIBLE)
                    .setDecimalVisibility(View.VISIBLE)
                    .setLabelText(getString(R.string.tage))
                    .setTargetFragment(this)
                    .setReference(v.getId());
            mMonatstagePicker.show();
        } else {
            int i = 1;
            int mSelectedTag = 0;
            do {
                if (v.getId() == wWochentage[i].getId()) {
                    mSelectedTag = i;
                    i = 8;
                }
                i++;
            } while (i <= 7);

            if (mSelectedTag > 0) {
                //Uhrzeit mZeit = new Uhrzeit(mArbeitsplatz.getTagSoll(mSelectedTag));
                //if(Einstellungen.mPreferenzen.getBoolean(Einstellungen.KEY_ANZEIGE_DEZIMAL, true)){
                if (mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)) {
                    NumberPickerBuilder zeitPicker = new NumberPickerBuilder()
                            .setFragmentManager(fragmentManager)
                            .setStyleResId(ASettings.themePicker)
                            .setMinNumber(BigDecimal.valueOf(0))
                            .setLabelText(getString(R.string.k_stunde))
                            .setPlusMinusVisibility(View.INVISIBLE)
                            .setDecimalVisibility(View.VISIBLE)
                            .setLabelText(getString(R.string.k_stunde))
                            .setReference(mSelectedTag)
                            .setTargetFragment(this);
                    zeitPicker.show();

                } else {
                    TimePickerBuilder zeitPicker = new TimePickerBuilder()
                            .setFragmentManager(fragmentManager)
                            .setTargetFragment(this)
                            .setReference(mSelectedTag)
                            .setStyleResId(ASettings.themePicker)
                            .addTimePickerDialogHandler(this);
                    zeitPicker.show();
                }

            }
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if(parent.getId() == R.id.I_spinner_modell) {
            if(position != mArbeitsplatz.getModell()) {
                mArbeitsplatz.setStundenmodell(position, (position == Arbeitsplatz.Soll_Monat_pauschal) ? 10965 : 2550);
                if(mArbeitsplatz.istGeaendert())
                    updateTagesliste();
            }
        } else {
            int mTag = 0;
            Uhrzeit mMinuten;

            int i = 1;
            do{
                if(parent.getId() == sWochentage[i].getId()) {
                    mTag = i;
                    i = 8;
                }
                i++;
            }while(i<=7);

            if(mTag > 0) {
                if( position != Math.round(mArbeitsplatz.getArbeitstag(mTag) * 2) ) {
                    switch (position) {
                        case ISettings.TAG_ARBEITSTAG:
                            mArbeitsplatz.setArbeitstag(mTag, true);
                            mArbeitsplatz.setArbeitstag(mTag + 7, true);
                            mMinuten = new Uhrzeit(mArbeitsplatz.getSollstundenTagPauschal());
                            break;
                        case ISettings.TAG_HALBFREI:
                            mArbeitsplatz.setArbeitstag(mTag, true);
                            mArbeitsplatz.setArbeitstag(mTag + 7, false);
                            mMinuten = new Uhrzeit(mArbeitsplatz.getSollstundenTagPauschal() / 2);
                            break;
                        default:
                            mArbeitsplatz.setArbeitstag(mTag, false);
                            mArbeitsplatz.setArbeitstag(mTag + 7, false);
                            mMinuten = new Uhrzeit(0);
                    }
                    wWochentage[mTag].setText(mMinuten.getStundenString(true, mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
                    wWochentage[mTag].setEnabled(!(mMinuten.getAlsMinuten() == 0));
                    mArbeitsplatz.setSollTag(mTag, mMinuten.getAlsMinuten());
                    setWochenstunden();
                }

            }
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }


    @Override
    public void onDialogNumberSet(final int reference, final BigInteger number, final double decimal, boolean isNegative, BigDecimal fullNumber) {
        //final Uhrzeit mZeit;
        MinutenInterpretationDialog.MinutenInterpretationDialogListener mListener = null;

        if (reference == R.id.I_wert_sollstunden) {
            mListener = z -> {
                mArbeitsplatz.setSollstundenWoche(z.getAlsMinuten(), true);
                wSollzeit.setText(z.getStundenString(true, mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
                setTageswerte();
            };
        } else if (reference == R.id.I_wert_monatstage) {
            mArbeitsplatz.setArbeitstage_Monat(fullNumber.floatValue());
            wMonatstage.setText(ASettings.zahlenformat.format(mArbeitsplatz.getArbeitstage_Monat()));
            setTageswerte();
        } else {
            if (reference > 0) {
                mListener = z -> {
                    mArbeitsplatz.setSollTag(reference, z.getAlsMinuten());
                    wWochentage[reference].setText(z.getStundenString(true, mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
                    setWochenstunden();
                };
            }
        }
        if (mListener != null) {
            new MinutenInterpretationDialog(
                    mContext,
                    mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL),
                    /*number,*/
                    decimal,
                    fullNumber,
                    mListener
            );
        }
    }

    @Override
    public void onDialogTimeSet(int reference, int hourOfDay, int minute) {
        if (reference > 0) {
            Uhrzeit mZeit = new Uhrzeit(hourOfDay, minute);
            mArbeitsplatz.setSollTag(reference, mZeit.getAlsMinuten());
            wWochentage[reference].setText(mZeit.getStundenString(true, mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
            setWochenstunden();
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(buttonView == wBezPause) {
            mArbeitsplatz.setOption(Arbeitsplatz.OPT_PAUSE_BEZAHLT, isChecked);
            updateView();
        }
    }
}
