/* 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.arbeitsmonat;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TableLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;

import java.math.BigDecimal;
import java.math.BigInteger;

import askanimus.arbeitszeiterfassung2.Datum;
import askanimus.arbeitszeiterfassung2.MinutenInterpretationDialog;
import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.Uhrzeit;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.betterpickers.numberpicker.NumberPickerBuilder;
import askanimus.betterpickers.numberpicker.NumberPickerDialogFragment;
import askanimus.betterpickers.timepicker.TimePickerBuilder;
import askanimus.betterpickers.timepicker.TimePickerDialogFragment;

/**
 * @author askanimus@gmail.com on 17.05.16.
 */
public class FragmentDialogSoll extends DialogFragment
        implements View.OnClickListener,
        NumberPickerDialogFragment.NumberPickerDialogHandlerV2,
        TimePickerDialogFragment.TimePickerDialogHandler{
    private EditSollDialogListener mListener;
    private int mEditSollDialog_tag;

    private Arbeitsplatz mJob;
    private Datum mMonat;
    private float sollTageMonat;
    private float anzahlWochen;
    private Uhrzeit sollWoche;
    private Uhrzeit sollTag;
    private Uhrzeit sollMonat;

    private TextView tTageMonat;
    private TextView tSollMonat;
    private TextView tSollWoche;
    private TextView tSollTag;

    private TextView tErgebnis;

    private Context mContext;


    public void setup(Arbeitsmonat monat, Arbeitsplatz job, EditSollDialogListener listener, int tag){
        mJob = job;
        mMonat = new Datum(monat.getJahr(), monat.getMonat(), 1, job.getWochenbeginn()); //Datum des betreffenden Monats
        // pauschale Wochensollstunden
        if(mJob.getModell() != Arbeitsplatz.Soll_Monat_pauschal){
           sollWoche = new Uhrzeit(mJob.getSollstundenWoche());
        } else {
            int mSoll = 0;
            for (int i = 0; i <= 6; i++) {
                mSoll += mJob.getSollstundenTag(i);
            }
            sollWoche = new Uhrzeit(mSoll);
        }

        sollTageMonat = monat.getSollArbeitstageGesamterMonat(false);
        anzahlWochen = sollTageMonat / 5;
        sollTag = new Uhrzeit(mJob.getSollstundenTagPauschal());   // pauschale Tages Sollstunden
        sollMonat = new Uhrzeit(monat.getSollBrutto());   // derzeitig errechnete Monats Sollstunden
        mListener = listener;
        mEditSollDialog_tag = tag;
    }


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getContext();
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        if(mJob != null) {
            LayoutInflater inflater = getLayoutInflater();

            View mInhalt = inflater.inflate(R.layout.fragment_edit_soll, null);
            mInhalt.setBackgroundColor(mJob.getFarbe_Hintergrund());

            TableLayout mTabelle = mInhalt.findViewById(R.id.ES_Tabelle);
            mTabelle.setBackgroundColor(mJob.getFarbe_Hintergrund());

            TextView tMonatDefault = mInhalt.findViewById(R.id.ES_errechnet_monat);
            TextView tWocheDefault = mInhalt.findViewById(R.id.ES_errechnet_wochen);
            TextView tTagDefault = mInhalt.findViewById(R.id.ES_errechnet_tage);
            TextView tSollDefault = mInhalt.findViewById(R.id.ES_errechnet_soll);


            tTageMonat = mInhalt.findViewById(R.id.ES_wert_mtage);
            tSollMonat = mInhalt.findViewById(R.id.ES_wert_msoll);
            tSollWoche = mInhalt.findViewById(R.id.ES_wert_wsoll);
            tSollTag = mInhalt.findViewById(R.id.ES_wert_tsoll);

            tErgebnis = mInhalt.findViewById(R.id.ES_wert_ergebnis);

            tTageMonat.setOnClickListener(this);
            tSollMonat.setOnClickListener(this);
            tSollWoche.setOnClickListener(this);
            tSollTag.setOnClickListener(this);

            tSollDefault.setText(sollMonat.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));

            tMonatDefault.setText(
                    getString(R.string.wert_monat, mMonat.getString_Monat_Jahr(mJob.getMonatsbeginn(), true))
            );

            tWocheDefault.setText(getString(
                    R.string.wert_wochen,
                    ASettings.zahlenformat.format(anzahlWochen/*mWoche*/),
                    sollWoche.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL))));

            tTagDefault.setText(getString(
                    R.string.wert_tage,
                    ASettings.zahlenformat.format(sollTageMonat),
                    sollTag.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL))));

            updateView();

            return new AlertDialog.Builder(getActivity())
                    .setView(mInhalt)
                    .setPositiveButton(android.R.string.ok, (dialog, which) -> mListener.onEditSollPositiveClick(mEditSollDialog_tag, sollMonat))
                    .setNegativeButton(android.R.string.cancel, (dialog, which) -> mListener.onEditSollNegativeClick(mEditSollDialog_tag))
                    .create();
        } else {
            return new AlertDialog.Builder(getActivity())
                    .create();
        }
    }


    private void updateView(){
        tSollWoche.setText(sollWoche.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
        tSollTag.setText(sollTag.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
        tTageMonat.setText(getString(R.string.wert_anzahl_Tage, ASettings.zahlenformat.format(sollTageMonat)));
        tSollMonat.setText(sollMonat.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
        tErgebnis.setText(sollMonat.getStundenString(true, mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)));
    }

    @Override
    public void onClick(View v) {
        FragmentManager mFragmentManager;
        try {
            mFragmentManager = getParentFragmentManager();
            int id = v.getId();
            if (id == R.id.ES_wert_tsoll) {
                if (mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL)) {
                    NumberPickerBuilder mZeitPicker = new NumberPickerBuilder()
                            .setFragmentManager(mFragmentManager)
                            .setStyleResId(ASettings.themePicker)
                            .setMinNumber(BigDecimal.valueOf(0))
                            .setLabelText(getString(R.string.k_stunde))
                            .setPlusMinusVisibility(View.INVISIBLE)
                            .setDecimalVisibility(View.VISIBLE)
                            .setReference(v.getId())
                            .setTargetFragment(this);
                    mZeitPicker.show();
                } else {
                    TimePickerBuilder tpb = new TimePickerBuilder()
                            .setFragmentManager(mFragmentManager)
                            .setTargetFragment(this)
                            .setReference(v.getId())
                            .setStyleResId(ASettings.themePicker)
                            .addTimePickerDialogHandler(this);
                    tpb.show();
                }
            } else if (id == R.id.ES_wert_wsoll || id == R.id.ES_wert_msoll || id == R.id.ES_wert_mtage) {
                NumberPickerBuilder mSollPicker = new NumberPickerBuilder()
                        .setFragmentManager(mFragmentManager)
                        .setStyleResId(ASettings.themePicker)
                        .setLabelText(getString(
                                (v.getId() == R.id.ES_wert_mtage) ? R.string.tag : R.string.k_stunde
                        ))
                        .setMinNumber(BigDecimal.valueOf(0))
                        .setPlusMinusVisibility(View.INVISIBLE)
                        .setDecimalVisibility(View.VISIBLE)
                        .setTargetFragment(this)
                        .setReference(v.getId());
                mSollPicker.show();
            }
        } catch (IllegalStateException ignore){
        }
    }

    @Override
    public void onDialogNumberSet(final int reference, final BigInteger number, final double decimal, boolean isNegative, BigDecimal fullNumber) {
        if (reference != R.id.ES_wert_mtage) {
            new MinutenInterpretationDialog(
                    mContext,
                    mJob.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL),
                    /*number,*/
                    decimal,
                    fullNumber,
                    z -> {
                        if (reference == R.id.ES_wert_wsoll) {
                            setSollWoche(z.getAlsMinuten());
                        } else if (reference == R.id.ES_wert_tsoll) {
                            setSollTag(z.getAlsMinuten());
                        } else if (reference == R.id.ES_wert_msoll) {
                            setSollMonat(z.getAlsMinuten());
                        }
                        updateView();
                    }

            );
        } else {
            setSollTageMonat(fullNumber.floatValue());
            updateView();
        }
    }

    @Override
    public void onDialogTimeSet(int reference, int hourOfDay, int minute) {
        Uhrzeit mZeit = new Uhrzeit(hourOfDay, minute);
        setSollTag(mZeit.getAlsMinuten());
        updateView();
    }


    private void setSollTageMonat(float tage) {
        sollTageMonat = tage;
        sollMonat.set(Math.round(tage*sollTag.getAlsMinuten()));
    }

    private void setSollMonat(int stunden){
        sollMonat.set(stunden);
        sollTag.set(
                (sollTageMonat == 0) ? 0 : Math.round(sollMonat.getAlsMinuten() / sollTageMonat)
        );
        if(mJob.getModell() == Arbeitsplatz.Soll_Woche_rollend) {
            sollWoche.set(Math.round(sollTag.getAlsMinuten() * 5));
        } else {
            if(sollTageMonat > 0) {
                sollWoche.set(Math.round(sollTag.getAlsMinuten() * mJob.getAnzahl_Arbeitstage_Woche()));
            } else {
                sollWoche.set(0);
            }
        }
    }

    private void setSollWoche(int stunden){
        sollWoche.set(stunden);
        if(mJob.getModell() == Arbeitsplatz.Soll_Woche_rollend)
           sollTag.set(Math.round(sollWoche.getAlsMinuten()/5.0f));
        else
            sollTag.set(Math.round(sollWoche.getAlsMinuten()/mJob.getAnzahl_Arbeitstage_Woche()));
        sollMonat.set(Math.round(sollTageMonat*sollTag.getAlsMinuten()));
    }

    private void setSollTag(int stunden){
        sollTag.set(stunden);
        sollMonat.set(Math.round(sollTageMonat*sollTag.getAlsMinuten()));
        if(mJob.getModell() == Arbeitsplatz.Soll_Woche_rollend)
           sollWoche.set(Math.round(sollTag.getAlsMinuten()*5));
        else
            sollWoche.set(Math.round(sollTag.getAlsMinuten()*mJob.getAnzahl_Arbeitstage_Woche()));
    }


    public interface EditSollDialogListener{
		void onEditSollPositiveClick(int dialog_tag, Uhrzeit wert);

		void onEditSollNegativeClick(int dialog_tag);
    }
}
