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

import android.content.Context;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;

import askanimus.arbeitszeiterfassung2.Datum;
import askanimus.arbeitszeiterfassung2.StorageHelper;
import askanimus.arbeitszeiterfassung2.Zeitraum.IZeitraum;
import askanimus.arbeitszeiterfassung2.abwesenheiten.Abwesenheit;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.arbeitsschicht.Arbeitsschicht;
import askanimus.arbeitszeiterfassung2.arbeitstag.Arbeitstag;
import askanimus.arbeitszeiterfassung2.feiertage.Feiertag;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;
import askanimus.arbeitszeiterfassung2.zusatzeintrag.IZusatzfeld;

class Export_ICS extends AExportBasis_CSV {
    private SimpleDateFormat datumFormatUhrzeit;
    private SimpleDateFormat datumFormatTag;
    IZeitraum mZeitraum;
    private BitSet mOptionen;
    private ArrayList<Arbeitsplatz> mArbeitsplatzListe;

    Export_ICS(
            Context context,
            IZeitraum zeitraum,
            BitSet optionen,
            StorageHelper storageHelper
            //String pfad
    ) throws Exception {
        super(context);
        mZeitraum = zeitraum;
        mOptionen = optionen;
        // Format der Datums- und Zeitangabe einer Terminzeile
        datumFormatUhrzeit = new SimpleDateFormat("HHmmss", Locale.getDefault());
        datumFormatTag = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());

        if(mOptionen.get(OPTION_ALL_JOBS)) {
           mArbeitsplatzListe = ASettings.jobListe.getListe();
        } else {
            mArbeitsplatzListe = new ArrayList<>();
            mArbeitsplatzListe.add(mZeitraum.getArbeitsplatz());
        }

        // den Dateiname zusammenstellen
        //String dateiname = mZeitraum.getDateiname(context, 0);
        //dateiname = ExportActivity.makeExportpfad(context, pfad, dateiname);

        schreibeTabelle(
                storageHelper,
                mZeitraum.getDateiname(context, 0),
                TYP_CAL_ICS
        );
    }


    public void erzeugeTermin(Arbeitsschicht schicht, Datum beginn) {
        Date dtStamp = new Date();
        Calendar mDatum = Calendar.getInstance();
        String sZeitstempel = String.format("%sT%s", datumFormatTag.format(dtStamp), datumFormatUhrzeit.format(dtStamp));

        // Beginn des Termineintrages

        ausgabeStream.println("BEGIN:VEVENT");

        // eindeutige Termin ID Datumsstempel-Username@Arbeitsplatzname
        ausgabeStream.println("UID:" +
                sZeitstempel +
                "-" + Objects.requireNonNull(ASettings.mPreferenzen.getString(ISettings.KEY_USERNAME, "")).
                replaceAll(ASettings.REG_EX_PFAD, "_") +
                "@" + Objects.requireNonNull(schicht.getArbeitsplatz().getName()).
                replaceAll(ASettings.REG_EX_PFAD, "_")
        );

        // Der Termineintrag
        if (schicht.getNameEinsatzort().isEmpty()) {
            ausgabeStream.println("LOCATION:" + schicht.getArbeitsplatz().getName()); // Arbeitsplatz
        } else {
            ausgabeStream.println("LOCATION:" + schicht.getNameEinsatzort()); // einsatzort
        }

        // Notizen aus Textfeldern der Schicht einsammeln
        /*if (!schicht.getBemerkung().isEmpty())
            ausgabeStream.println("DESCRIPTION:" + schicht.getBemerkung()); // Notiz*/
        StringBuilder mNotiz = new StringBuilder();
        for (IZusatzfeld zf : schicht.getZusatzfelder(IZusatzfeld.TEXT_VOLL).getListe()) {
            if (zf.getDatenTyp() == IZusatzfeld.TYP_TEXT) {
                mNotiz.append(zf.getString(false)).append(" ");
            }
        }
        if(mNotiz.length() > 0){
           ausgabeStream.println("DESCRIPTION:" + mNotiz);
        }

        ausgabeStream.println("DTSTAMP:" + sZeitstempel);// Zeitstempel YYYYMMDDTHHMMSSZ

        // Terminname um den Schichtnamen ergänzem, wenn es Arbeitszeit ist
        // Arbeitszeit und Schule als öffentlicher Termin andere privat
        String sTerminnname;
        switch (schicht.getAbwesenheit().getKategorie()) {
            case Abwesenheit.KAT_ARBEITSZEIT:
                sTerminnname = "SUMMARY:" + schicht.getAbwesenheit().getName();
                if (!schicht.getName().isEmpty())
                    sTerminnname += "(" + schicht.getName() + ")";
                ausgabeStream.println("CLASS:PUBLIC"); // Terminart
                break;
            case Abwesenheit.KAT_SCHULE:
                sTerminnname = "SUMMARY:" + schicht.getAbwesenheit().getName();
                ausgabeStream.println("CLASS:PUBLIC"); // Terminart
                break;
            case Abwesenheit.KAT_FEIERTAG:
                Feiertag feiertag = ASettings.feiertage.getFeiertag(beginn);
                if (feiertag != null) {
                   sTerminnname = "SUMMARY:" + feiertag.getName();
                } else {
                    sTerminnname = "SUMMARY:" + schicht.getAbwesenheit().getName();
                }
                ausgabeStream.println("CLASS:PRIVATE"); // Terminart
                break;
            default:
                sTerminnname = "SUMMARY:" + schicht.getAbwesenheit().getName();
                ausgabeStream.println("CLASS:PRIVATE"); // Terminart
        }
        ausgabeStream.println(sTerminnname);

        // alle An- bzw. abwesenheiten mit pauschalen Zeiten als ganztägigen Termin eintragen
        if (schicht.getAbwesenheit().getWirkung() == Abwesenheit.WIRKUNG_IST_PLUS_EFFEKTIV ||
                schicht.getAbwesenheit().getWirkung() == Abwesenheit.WIRKUNG_SOLL_MINUS_EFFEKTIV) {
            mDatum.setTimeInMillis(beginn.getTimeInMillis());
            mDatum.add(Calendar.MINUTE, schicht.getVon());
            sZeitstempel = String.format("%sT%s", datumFormatTag.format(mDatum.getTime()), datumFormatUhrzeit.format(mDatum.getTime()));
            ausgabeStream.println("DTSTART:" + sZeitstempel); // Start YYYYMMDDTHHMMSSZ
            mDatum.add(Calendar.MINUTE, schicht.getBrutto());
            sZeitstempel = String.format("%sT%s", datumFormatTag.format(mDatum.getTime()), datumFormatUhrzeit.format(mDatum.getTime()));
            ausgabeStream.println("DTEND:" + sZeitstempel); // Ende YYYYMMDDTHHMMSSZ
        } else {
            ausgabeStream.println("DTSTART;VALUE=DATE:" + datumFormatTag.format(beginn.getDate())); // Start YYYYMMDD
            ausgabeStream.println("DTEND;VALUE=DATE:" + datumFormatTag.format(beginn.getDate())); // Start YYYYMMDD
        }
        //Ende
        ausgabeStream.println("END:VEVENT");
    }

    @Override
    public  void schreibeSeiten() {
        // Vorspann schreiben
        ausgabeStream.println("BEGIN:VCALENDAR");
        ausgabeStream.println("VERSION:2.0");
        ausgabeStream.println("PRODID:askanimus.Arbeitszeitkonto");
        ausgabeStream.println("METHOD:PUBLISH");
        ausgabeStream.println("TZID:"+ Calendar.getInstance().getTimeZone().getID());

        for (Arbeitsplatz a:mArbeitsplatzListe) {
           if(mZeitraum.getArbeitsplatz().getId() != a.getId()) {
               mZeitraum = mZeitraum.wechselArbeitsplatz(a);
           }

            // die Termine schreiben
            for (Arbeitstag tag : mZeitraum.getTage()) {
                for (Arbeitsschicht schicht : tag.getSchichten()) {
                    if (schicht.getAbwesenheit().getKategorie() != Abwesenheit.KAT_KEINESCHICHT) {
                        erzeugeTermin(schicht, tag.getKalender());
                    }
                }
            }
        }
        //Abspann schreiben
        ausgabeStream.println("END:VCALENDAR");
    }

    @Override
    public ArrayList<ArrayList<Zelle_CSV>> erzeugeTabelle() {
        return null;
    }
}
