package askanimus.arbeitszeiterfassung2.datensicherung;

import static askanimus.arbeitszeiterfassung2.datensicherung.Datensicherung_Activity.INPUTSTREAM_LAENGE;
import static askanimus.arbeitszeiterfassung2.datensicherung.Datensicherung_Activity.UPDATE_INTEVAL;

import android.content.Context;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile;
import androidx.recyclerview.widget.RecyclerView;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;
import java.util.Objects;

import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.StorageHelper;
import askanimus.arbeitszeiterfassung2.setup.ASettings;


public class Datensicherung_ViewAdapter
        extends RecyclerView.Adapter<Datensicherung_ViewAdapter.ViewHolder>  {
    public final static int ACTION_ITEM = 0;
    public final static int ACTION_RESTORE = 1;
    public final static int ACTION_DELETE = 2;
    public final static int ACTION_SEND = 3;

    private Context mContext;
    private StorageHelper mStorageHelper;
    private ItemClickListener mClickListener;
    private ArrayList<String> fSicherungen;
    private boolean mitIcons = false;

    public ArrayList<String> setUp(Context context, StorageHelper storageHelper, ItemClickListener clickListener, boolean mitActionIcons){
        mContext = context;
        mStorageHelper = storageHelper;
        fSicherungen = new ArrayList<>();
        mClickListener = clickListener;
        mitIcons = mitActionIcons;
        read();
        //sort();
        return fSicherungen;
    }

    private void read(){
        // Liste einlesen
        Handler mHandler = new Handler();
        new Thread(() -> {
            int i = UPDATE_INTEVAL;
            String file_name;
            // Dateien einlesen und abgleichen, ob es sich um Sicherungen handelt
            DocumentFile dir = mStorageHelper.getVerzeichnisFile();
            if (dir != null && dir.exists()) {
                for (DocumentFile docFile : dir.listFiles()) {
                    // ist es eine Datei?
                    if (docFile.isFile()) {
                        file_name = docFile.getName();
                        if (file_name != null) {
                            if (file_name.endsWith(".db")) {
                                fSicherungen.add(file_name);
                            } else {
                                // ist es eine XML Datei
                                try {
                                    // öffnet die Datei und liesst die ersten 46 Zeichen
                                    InputStream inputStream = mContext
                                            .getContentResolver()
                                            .openInputStream(docFile.getUri());
                                    if (inputStream != null) {
                                        byte[] bytes = new byte[INPUTSTREAM_LAENGE];
                                        try {
                                            int size = inputStream.read(bytes, 0, INPUTSTREAM_LAENGE);
                                            ByteArrayOutputStream bs = new ByteArrayOutputStream(INPUTSTREAM_LAENGE);
                                            bs.write(bytes);
                                            // enthält der gelesene Teil der Datei am Ende den Schlüssel <backup>
                                            // ist es eine Sicherungsdatei
                                            if (bs.toString().endsWith("<backup>")) {
                                                fSicherungen.add(file_name);
                                                if (i <= 0) {
                                                    mHandler.post(
                                                            () -> notifyItemInserted(
                                                                    fSicherungen.size() - 1
                                                            )
                                                    );
                                                    i = UPDATE_INTEVAL;
                                                }
                                                i--;
                                            }
                                            inputStream.close();
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                } catch (FileNotFoundException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
            // die Liste sortieren
            mHandler.post(this::sort);
        }).start();

    }

    public void sort() {
        // Die Liste aufsteigend nach Dateiname (Datum und Uhrzeit) sortieren
        if (fSicherungen != null) {
            Collections.sort(fSicherungen, new Comparator<String>() {
                final DateFormat f = new SimpleDateFormat(
                        "dd-MM-yyyy_hh.mm.ss",
                        Locale.getDefault()
                );

                @Override
                public int compare(String o1, String o2) {
                    if (o1 == null) {
                        o1 = "";
                    } else {
                        o1 = o1.replace(".xml", "");
                        o1 = o1.replace(".db", "");
                        o1 = o1.replace(ASettings.res.getString(R.string.sich_vom_datei), "");
                    }
                    if (o2 == null) {
                        o2 = "";
                    } else {
                        o2 = o2.replace(".xml", "");
                        o1 = o1.replace(".db", "");
                        o2 = o2.replace(ASettings.res.getString(R.string.sich_vom_datei), "");
                    }

                    try {
                        return Objects.requireNonNull(f.parse(o2)).compareTo(f.parse(o1));
                    } catch (ParseException e) {
                        return o2.compareTo(o1);
                    }
                }
            });
            notifyDataSetChanged();
        }
    }

    @NonNull
    @Override
    public Datensicherung_ViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater mInflater = LayoutInflater.from(parent.getContext());
        return new ViewHolder(mInflater.inflate(
                R.layout.item_datensicherung,
                parent,
                false));
    }

    @Override
    public void onBindViewHolder(@NonNull Datensicherung_ViewAdapter.ViewHolder holder, int position) {
        if (fSicherungen != null && position < fSicherungen.size()){
            String sDatum;
            sDatum = fSicherungen.get(position).replace(".xml", "");
            sDatum = sDatum.replace(".db", "");
            sDatum = sDatum.replace(ASettings.res.getString(R.string.sich_vom_datei), "");
            sDatum = sDatum.replace(".", ":");
            sDatum = sDatum.replace("_", " ");
            sDatum = sDatum.replace("-", ".");

            holder.tPfad.setText(sDatum);
        }
    }

    @Override
    public int getItemCount() {
        if(fSicherungen != null){
            return fSicherungen.size();
        }
        return 0;
    }

    private String getItem(int position) {
        if(position < getItemCount()){
            return fSicherungen.get(position);
        }
        return null;
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView tPfad;
        ImageView iRestore;
        ImageView iDelete;
        ImageView iSend;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            itemView.setBackgroundColor(ASettings.aktJob.getFarbe_Tag());
            itemView.setOnClickListener(this);
            tPfad = itemView.findViewById(R.id.ID_wert_datum);
            iRestore = itemView.findViewById(R.id.ID_button_restore);
            iDelete = itemView.findViewById(R.id.ID_button_delete);
            iSend = itemView.findViewById(R.id.ID_button_send);
            if(mitIcons) {
                iRestore.setOnClickListener(this);
                iDelete.setOnClickListener(this);
                iSend.setOnClickListener(this);
            } else {
                iRestore.setVisibility(View.GONE);
                iDelete.setVisibility(View.INVISIBLE);
                iSend.setVisibility(View.INVISIBLE);
            }
        }

        @Override
        public void onClick(View v) {
            if(mClickListener != null){
                int id = v.getId();
                if (id == R.id.ID_button_restore){
                    mClickListener.onSicherungClick(getAdapterPosition(), ACTION_RESTORE, v);
                } else if (id == R.id.ID_button_delete){
                    mClickListener.onSicherungClick(getAdapterPosition(), ACTION_DELETE, v);
                } else if (id == R.id.ID_button_send){
                    mClickListener.onSicherungClick(getAdapterPosition(), ACTION_SEND, v);
                } else {
                    mClickListener.onSicherungClick(getAdapterPosition(), ACTION_ITEM, v);
                }
            }
        }
    }

    // Klicks in die aufrufende Activity durchreichen
    public interface ItemClickListener {
        void onSicherungClick(int position, int action, View view);
    }
}
