package com.bernard.mcqinator.view.activities;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.bernard.mcqinator.R;
import com.bernard.mcqinator.api.IdentifiedQuiz;
import com.bernard.mcqinator.api.QuizMetadata;
import com.bernard.mcqinator.api.frageable.Frageable;
import com.bernard.mcqinator.api.fragen.Frage;
import com.bernard.mcqinator.api.fragenStats.QuizStat;
import com.bernard.mcqinator.api.quiz.Quiz;
import com.bernard.mcqinator.controller.FileManager;
import com.bernard.mcqinator.controller.QuizMetadataManager;
import com.bernard.mcqinator.inutil.ClassInutil;
import com.bernard.mcqinator.view.activities.congratsActivity.CongratsActivity;
import com.bernard.mcqinator.view.activities.fragenActivities.FrageActivity;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ConfiguringQuizActivity extends Activity implements AdapterView.OnItemClickListener,View.OnClickListener{

    public static final String QUIZID = "com.bernard.qcminator.QUIZID";
    private static final int MAKE_QUIZ = 0x6C98E2AA;
    private static final int CONGRATS_QUIZ = 0x2843124F;
    public ProgressDialog fragment;

    QuizMetadata q;
    Quiz quiz;

    FrameLayout frame;
    ListView list;
    View actualView;
    Button go;
    Frage[] fragen;
    LinkedHashMap<Class,View> classes;// <The XFrageable class,The hided view with settings>
    LinkedHashMap<Class,Frageable.Configurator> configurators;// <The XFrageable class,Configurator>
    private Class actualClass;
    private Frage.Identifier storedIdentifier;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_configuring_quiz);
        long quizID = getIntent().getLongExtra(QUIZID,-1L);
        if(quizID == -1L)throw new IllegalArgumentException("Missing long "+QUIZID+" in the intent");
        q = QuizMetadataManager.getQuiz(this,quizID);

        frame = findViewById(R.id.attributesFrame);
        list = findViewById(android.R.id.list);
        go = findViewById(R.id.doneButton);

        fragment = new ProgressDialog(ConfiguringQuizActivity.this);

        classes = new LinkedHashMap<>();
        configurators = new LinkedHashMap<>();

        for (Class i : ClassInutil.getAllInterface(q.getType().getQuizClass())) {
            if(!Frageable.class.isAssignableFrom(i))
                continue;
            try {
                Class configuratorClass = Class.class.cast(i.getField("CONFIGURATOR").get(null));
                Frageable.Configurator configurator = (Frageable.Configurator) configuratorClass.newInstance();
                View added = configurator.attachConfigLayout(this,frame);
                added.setVisibility(View.GONE);
                configurators.put(i,configurator);
                classes.put(i,added);
            } catch (IllegalAccessException e) {
                Log.e("ClassError","The field CONFIGURATOR of the class "+i+" is not public");
            } catch (NoSuchFieldException e) {
                Log.e("ClassError","The class "+i+" don't have the field CONFIGURATOR");
            } catch (InstantiationException e) {
                Log.e("ClassError","Cannot instantiate the CONFIGURATOR of class "+i+" , do you have a public constructor ?");
            } catch (ClassCastException e) {
                Log.e("ClassError","The CONFIGURATOR of class "+i+" is not a Class<? extends Frageable.Configurator>");
            }

        }
        Log.d("ConfiguringQuizActivity","Quiz Frageable Classes : " + classes.toString());
        list.setAdapter(new QuizFrageableAdapter());
        list.setOnItemClickListener(this);

        go.setOnClickListener(this);
    }


    protected void launchQuiz(final Frageable.Data data){
        final Context me = this;
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    quiz = FileManager.getQuiz(q,me);
                } catch (IOException e) {
                    Log.e("ConfiguringQuizActivity","Cannot retieve Quiz data ... aborting quiz launch",e);
                }
                if(quiz == null)
                    Toast.makeText(me, R.string.cannotLaunchQuiz, Toast.LENGTH_SHORT).show();

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        fragment.setTitle("WaitingDialog");
                        fragment.setMessage("Chargement de votre quiz en cours ...");
                        fragment.setIndeterminate(true);
                        fragment.show();
                    }
                });

                Frageable f = (Frageable)quiz;

                QuizStat stats = FileManager.getStat(q,me);
                if(stats == null){
                    stats = QuizStat.createStat(q.getType().getQuizStatClass(),quiz);
                    FileManager.saveStat(q,stats,me);
                }
                IdentifiedQuiz identifiedQuiz = checkedGenFragen(f,stats,data,fragment);
                storedIdentifier = identifiedQuiz.getIdentifier();
                fragen = identifiedQuiz.getFragen();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        fragment.hide();
                        Intent i = new Intent(ConfiguringQuizActivity.this,data.getFrageActivityClass());
                        i.putExtra(FrageActivity.FRAGEN,fragen);
                        i.putExtra(FrageActivity.QUIZ_DATA,data);
                        startActivityForResult(i,ConfiguringQuizActivity.MAKE_QUIZ);
                    }
                });
            }
        },"QuizLauncherThread");
        t.start();
    }

    @SuppressWarnings("unchecked")
    private IdentifiedQuiz checkedGenFragen(Frageable f, QuizStat stats, Frageable.Data data, ProgressDialog wait){
        return f.genFragen(stats,data,this,wait);//Normal Warning
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == MAKE_QUIZ && resultCode == RESULT_OK){
            ArrayList<? extends Frage.Reply> repliesList = data.getParcelableArrayListExtra(FrageActivity.REPLIES);
            QuizStat stats = FileManager.getStat(q,this);
            stats = checkedUpdateStats((Frageable) quiz,stats,repliesList,storedIdentifier);
            FileManager.saveStat(q,stats,this);
            Intent i = new Intent(ConfiguringQuizActivity.this,q.getType().getCongratsActivityClass());
            i.putExtra(CongratsActivity.FRAGEN,fragen);
            i.putParcelableArrayListExtra(CongratsActivity.REPLIES,repliesList);
            i.putExtra(CongratsActivity.QUIZ_DATA,q);
            startActivityForResult(i,ConfiguringQuizActivity.CONGRATS_QUIZ);
        }else if(requestCode == CONGRATS_QUIZ && resultCode == RESULT_OK){
            Log.d("ConfiguringQuizActivity","Congrats made !");
        }
    }

    @SuppressWarnings("unchecked")
    private QuizStat checkedUpdateStats(Frageable f, QuizStat stats, List<? extends Frage.Reply> replies, Frage.Identifier identifier){
        return f.updateStats(stats,replies,identifier);//Normal Warning
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if(actualView != null)
            actualView.setVisibility(View.GONE);
        Map.Entry[] entries = new Map.Entry[classes.size()];
        classes.entrySet().toArray(entries);
        actualClass = (Class) entries[position].getKey();
        actualView = classes.get(actualClass);
        actualView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onClick(View v) {
        if(actualClass == null)return;
        Frageable.Configurator configurator = configurators.get(actualClass);
        Frageable.Data data = configurator.genDataFromConfigLayout(actualView);
        launchQuiz(data);

    }

    private class QuizFrageableAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return classes.size();
        }

        @Override
        public Class getItem(int position) {
            return (Class) classes.keySet().toArray()[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewGroup lay;
            TextView text;
            ImageView image;
            if(convertView == null)
                lay = (ViewGroup)getLayoutInflater().inflate(R.layout.quiz_typ_row_layout,parent,false);
            else
                lay = (ViewGroup)convertView;
            text = lay.findViewById(R.id.quizTypText);
            image = lay.findViewById(R.id.quizTypIcon);
            Frageable.Configurator configurator = configurators.get(getItem(position));
            text.setText(configurator.getTypStringID());
            int drawableID = configurator.getIconDrawableID();
            image.setImageDrawable(getDrawable(drawableID));


            return lay;
        }
    }
}
