package org.example.proyecto;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Calendar;
import java.util.Vector;
import java.util.concurrent.ExecutionException;

/**
 * Created by Victor on 05/09/2016.
 */
public class AdaptadorCiudades extends
        RecyclerView.Adapter<AdaptadorCiudades.ViewHolder> {

    public String urlTiempo = "http://api.openweathermap.org/data/2.5/weather?q=";
    public String urlForecast = "http://api.openweathermap.org/data/2.5/forecast/daily?q=";
    public String cnt = "&cnt=6";
    public String units = "&units=metric";
    public String lang = "&lang=sp";
    public String appid = "&appid=9c64b7863274b6a1c301966af6c0f57e";
    public String imgUrl = "http://openweathermap.org/img/w/";
    public String json;

    public JSONObject jObj,coordObj,mainObj,windObj,cloudsObj,sysObj,weatherObj,rainObj;
    public JSONArray weatherArr;

    //forecast
    public JSONArray listArr;
    public JSONObject listObj,tempObj;
    public int dt;

    public static float lon,lat,temp,pressure,humidity,temp_min,temp_max,speed,deg,rain;
    public static String weatherMain,description,icon,country,name;
    public static String windDirection = null;
    public static int error,weatherId,sunrise,sunset;

    public static Bitmap imgBitmap,bitmapIcon;

    public ProgressDialog progreso;
    public int posicion;

    public Activity a;
    public Context c;

    public AlmacenCiudadesPreferencias almacen;

    private LayoutInflater inflador;      //Crea Layouts a partir del XML
    protected Vector<Ciudad> vectorCiudades; //Vector con Ciudades a visualizar
    protected Vector<Ciudad> vectorPrediccion; //Vector con Ciudades a visualizar

    private View.OnClickListener onClickListener;
    private View.OnLongClickListener onLongClickListener;

    private Vector<Integer> indiceVector; // Índice en vectorCiudades de cada elemento de vectorCiudades

    ViewHolder h;

    Calendar calendar = Calendar.getInstance();

    public static boolean correr = false;
    public static boolean tenis = false;
    public static String ciudad;
    SharedPreferences pref;

    public ProgressDialog progress;



    public AdaptadorCiudades(Context contexto, Vector<Ciudad> vectorCiudades) {
        inflador = (LayoutInflater) contexto.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.vectorCiudades = vectorCiudades;
        almacen = new AlmacenCiudadesPreferencias(contexto);
        pref = PreferenceManager.getDefaultSharedPreferences(contexto);
    }

    //Creamos nuestro ViewHolder, con los tipos de elementos a modificar
    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView nombreCiudad;
        public TextView tempAdaptador;
        public ImageView imageAdaptador;
        public TextView tempDescription;
        public TextView actualizacion;
        public TextView textSeleccionada;

        public ViewHolder(View itemView) {
            super(itemView);
            nombreCiudad = (TextView) itemView.findViewById(R.id.nombreCiudad);
            tempAdaptador = (TextView) itemView.findViewById(R.id.tempAdaptador);
            tempDescription = (TextView) itemView.findViewById(R.id.tempDescription);
            imageAdaptador = (ImageView) itemView.findViewById(R.id.imageAdaptador);
            actualizacion = (TextView) itemView.findViewById(R.id.actualizacion);
            textSeleccionada = (TextView) itemView.findViewById(R.id.textSeleccionada);
        }
    }

    // Creamos el ViewHolder con las vista de un elemento sin personalizar
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // Inflamos la vista desde el xml
        View v = inflador.inflate(R.layout.elemento_selector, null);
        v.setOnClickListener(onClickListener);
        v.setOnLongClickListener(onLongClickListener);
        return new ViewHolder(v);
    }

    // Usando como base el ViewHolder y lo personalizamos
    @Override
    public void onBindViewHolder(ViewHolder holder, int posicion) {
        Ciudad Ciudad = vectorCiudades.elementAt(posicion);
        holder.nombreCiudad.setText(Ciudad.nombreCiudad);

        holder.tempAdaptador.setText(String.valueOf(Ciudad.tiempoActual.temp)+"º");
        holder.tempDescription.setText(Ciudad.tiempoActual.description);
        holder.imageAdaptador.setImageBitmap(Ciudad.tiempoActual.bitmapIcon);
        holder.actualizacion.setText(Ciudad.tiempoActual.actualizacion);

        if (Ciudad.seleccionada){
            holder.textSeleccionada.setVisibility(View.VISIBLE);
        } else {
            holder.textSeleccionada.setVisibility(View.GONE);
        }
    }

    // Indicamos el número de elementos de la lista
    @Override public int getItemCount() {
        return vectorCiudades.size();
    }

    public void setOnItemClickListener(View.OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public void setOnItemLongClickListener(View.OnLongClickListener onLongClickListener) {
        this.onLongClickListener = onLongClickListener;
    }

    public Ciudad getItem(int posicion) {
        return vectorCiudades.elementAt(indiceVector.elementAt(posicion));
    }

    public long getItemId(int posicion) {
        return indiceVector.elementAt(posicion);
    }

    public void borrar(int posicion){
        vectorCiudades.removeElementAt(posicion);
    }

    public void insertar(Ciudad Ciudad){
        vectorCiudades.add(0,Ciudad);
    }



    public void recargarClima(Activity a,Context c,boolean dialog){

        this.a = a;
        this.c = c;

        if (dialog)
            progreso = ProgressDialog.show(c, "Cargando", "Actualizando clima", true);

        MiThread hilo = new MiThread(a,c,dialog);
        hilo.start();

    }

    public void actualizarAlmacen(Activity a,Context c,AdaptadorCiudades adaptador,boolean dialog){

        if (vectorCiudades.size()==0){
            recargarClima(a,c,dialog);
            almacen.getVectorCiudades(adaptador);
        }

    }


    public void obtenerClima(String nombreCiudad){

        TareaWeb tarea = new TareaWeb();
        tarea.execute(urlTiempo+nombreCiudad+units+lang+appid);

        // Obtener el resultado del AsyncTask
        try {
            json = tarea.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }


        // We create out JSONObject from the data
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            e.printStackTrace();
        }


        // We start extracting the info

        try {
            coordObj = getObject("coord", jObj);
            lon = getFloat("lon", coordObj);
            lat = getFloat("lat", coordObj);
        } catch (JSONException e) {
            e.printStackTrace();
        }


        try {
            // We get weather info (This is an array)
            weatherArr = jObj.getJSONArray("weather");

            // We use only the first value
            weatherObj = weatherArr.getJSONObject(0);
            weatherId = getInt("id", weatherObj);
            description = getString("description", weatherObj);
            weatherMain = getString("main", weatherObj);
            icon = getString("icon", weatherObj);
        } catch (JSONException e) {
            e.printStackTrace();
        }


        try {
            mainObj = getObject("main", jObj);
            temp = getFloat("temp", mainObj);
            pressure = getFloat("pressure", mainObj);
            humidity = getFloat("humidity", mainObj);
            temp_min = getFloat("temp_min", mainObj);
            temp_max = getFloat("temp_max", mainObj);
        } catch (JSONException e) {
            e.printStackTrace();
        }


        try {
            sysObj = getObject("sys", jObj);
            country = getString("country", sysObj);
            sunrise = getInt("sunrise", sysObj);
            sunset = getInt("sunset", sysObj);
        } catch (JSONException e) {
            e.printStackTrace();
        }


        try {
            name = getString("name", jObj);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try{
            windObj = getObject("wind",jObj);
            speed = getFloat("speed",windObj);
            deg = getFloat("deg",windObj);

            int deg_int = (int) deg;

            WindDirection wD;
            wD = WindDirection.valueOf(deg_int);
            windDirection = wD.toString();

        } catch (JSONException e) {
        e.printStackTrace();
        }

        try{
            rainObj = getObject("rain",jObj);

            for (int i=0;i<10;i++){
                try {
                    rain = getFloat(String.valueOf(i)+"h", rainObj);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        bitmapIcon = obtenerIcono(icon);
    }

    public void obtenerPrediccion(String nombreCiudad, int posicion){

        TareaWeb tarea = new TareaWeb();
        tarea.execute(urlForecast+nombreCiudad+cnt+units+lang+appid);

        // Obtener el resultado del AsyncTask
        try {
            json = tarea.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        // We create out JSONObject from the data
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        /*for (int j=0;j<vectorCiudades.size();j++) {
            if (vectorCiudades.elementAt(j).nombreCiudad.equals(nombreCiudad)) {
                posicion = j;
                break;
            }
        }*/


        // We start extracting the info
        try {
            listArr = jObj.getJSONArray("list");

            for (int i=0;i<=4;i++){

                try {
                    listObj = listArr.getJSONObject(i + 1);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                try {
                    dt = getInt("dt", listObj);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                try {
                    tempObj = getObject("temp", listObj);
                    //temp = getFloat("temp", mainObj);
                    temp_min = getFloat("min", tempObj);
                    temp_max = getFloat("max", tempObj);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                try {
                    pressure = getFloat("pressure", listObj);
                    humidity = getFloat("humidity", listObj);
                    //sea_level = getFloat("sea_level", mainObj);
                    //grnd_level = getFloat("grnd_level", mainObj);
                    //temp_kf = getFloat("temp_kf", mainObj);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                try {
                    weatherArr = listObj.getJSONArray("weather");
                    weatherObj = weatherArr.getJSONObject(0);
                    weatherId = getInt("id", weatherObj);
                    description = getString("description", weatherObj);
                    weatherMain = getString("main", weatherObj);
                    icon = getString("icon", weatherObj);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                //dt_txt = getString("dt_txt", listObj);

                //windObj = listObj.getJSONObject("wind");

                try {
                    speed = getFloat("speed", listObj);
                    deg = getFloat("deg", listObj);

                    int deg_int = (int) deg;

                    WindDirection wD;
                    wD = WindDirection.valueOf(deg_int);
                    windDirection = wD.toString();

                } catch (JSONException e) {
                    e.printStackTrace();
                }

                bitmapIcon = obtenerIcono(icon);


                PrediccionTiempo prediccionTiempo = new PrediccionTiempo(vectorCiudades.elementAt(posicion).nombreCiudad);

                vectorCiudades.elementAt(posicion).vectorPrediccion.add(prediccionTiempo);
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).dt = dt;
                //vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).temp = temp;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).temp_min = temp_min;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).temp_max = temp_max;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).pressure = pressure;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).humidity = humidity;
                //vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).sea_level = sea_level;
                //vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).grnd_level = grnd_level;
                //vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).temp_kf = temp_kf;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).weatherId = weatherId;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).description = description;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).weatherMain = weatherMain;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).bitmapIcon = bitmapIcon;
                //vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).dt_txt = dt_txt;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).speed = speed;
                vectorCiudades.elementAt(posicion).vectorPrediccion.elementAt(i).windDirection = windDirection;


            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }


    public Bitmap obtenerIcono(String icono){

        TareaImg tarea = new TareaImg();
        tarea.execute(new String[]{imgUrl + icono +".png"});

        try {
            imgBitmap = tarea.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return imgBitmap;
    }



    private static JSONObject getObject(String tagName, JSONObject jObj) throws JSONException {
        JSONObject subObj = jObj.getJSONObject(tagName);
        return subObj;
    }

    private static String getString(String tagName, JSONObject jObj) throws JSONException {
        return jObj.getString(tagName);
    }

    private static float getFloat(String tagName, JSONObject jObj) throws JSONException {
        return (float) jObj.getDouble(tagName);
    }

    private static int getInt(String tagName, JSONObject jObj) throws JSONException {
        return jObj.getInt(tagName);
    }



    public class MiThread extends Thread {

        Activity a;
        Context c;
        boolean dialog;

        public MiThread(Activity a,Context c,boolean dialog){
            this.a = a;
            this.c = c;
            this.dialog = dialog;
        }

        @Override
        public void run() {

            for (int i=0;i<vectorCiudades.size();i++){

                obtenerClima(vectorCiudades.elementAt(i).nombreCiudadUrl);

                vectorCiudades.elementAt(i).tiempoActual.weatherId = weatherId;
                vectorCiudades.elementAt(i).tiempoActual.description = description;
                vectorCiudades.elementAt(i).tiempoActual.weatherMain = weatherMain;
                vectorCiudades.elementAt(i).tiempoActual.bitmapIcon = bitmapIcon;
                vectorCiudades.elementAt(i).tiempoActual.temp = temp;
                vectorCiudades.elementAt(i).tiempoActual.pressure = pressure;
                vectorCiudades.elementAt(i).tiempoActual.humidity = humidity;
                vectorCiudades.elementAt(i).tiempoActual.temp_min = temp_min;
                vectorCiudades.elementAt(i).tiempoActual.temp_max = temp_max;
                vectorCiudades.elementAt(i).tiempoActual.sunrise = sunrise;
                vectorCiudades.elementAt(i).tiempoActual.sunset = sunset;
                vectorCiudades.elementAt(i).tiempoActual.speed = speed;
                vectorCiudades.elementAt(i).tiempoActual.windDirection = windDirection;
                vectorCiudades.elementAt(i).tiempoActual.rain = rain;

                vectorCiudades.elementAt(i).tiempoActual.actualizacion =
                        String.valueOf(calendar.get(Calendar.HOUR_OF_DAY) + ":" +
                                String.valueOf(calendar.get(Calendar.MINUTE)) + ":" +
                                String.valueOf(calendar.get(Calendar.SECOND)) + " " +
                                String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)) +"/"+
                                String.valueOf((calendar.get(Calendar.MONTH))+1)+"/"+
                                String.valueOf(calendar.get(Calendar.YEAR)));

                obtenerPrediccion(vectorCiudades.elementAt(i).nombreCiudadUrl,i);


                a.runOnUiThread(new Runnable(){
                    @Override public void run(){
                        notifyDataSetChanged();
                    }
                });
            }

            a.runOnUiThread(new Runnable(){

                @Override public void run(){

                    notifyDataSetChanged();

                    comprobarCondicion(c);

                    if (dialog) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(c);
                        builder.setMessage("Clima actualizado correctamente");
                        builder.setPositiveButton(android.R.string.ok, null);
                        builder.create().show();

                        progreso.dismiss();
                    }

                }

            });

        }

    }




    public void comprobarCondicion(Context c){

        if (vectorCiudades.size()==0)
            almacen.getVectorCiudades(this);

        if (pref.getBoolean("activar_correr", true)) {

            for (int i=0;i<vectorCiudades.size();i++){

                if (vectorCiudades.elementAt(i).tiempoActual.rain == 0 &&
                        vectorCiudades.elementAt(i).tiempoActual.speed < 30 &&
                        vectorCiudades.elementAt(i).tiempoActual.temp > -10 &&
                        vectorCiudades.elementAt(i).tiempoActual.temp < 35 &&
                        vectorCiudades.elementAt(i).seleccionada){

                    ciudad = vectorCiudades.elementAt(i).nombreCiudad;

                    correr = true;

                    Intent intent = new Intent (c,ServicioNotificacion.class);
                    c.startService(intent);

                }
            }
        } else {
            correr = false;
        }

        if (pref.getBoolean("activar_tenis", true)) {

            for (int i=0;i<vectorCiudades.size();i++){

                if (vectorCiudades.elementAt(i).tiempoActual.rain == 0 &&
                        vectorCiudades.elementAt(i).tiempoActual.speed < 5 &&
                        vectorCiudades.elementAt(i).tiempoActual.temp > -10 &&
                        vectorCiudades.elementAt(i).tiempoActual.temp < 35 &&
                        vectorCiudades.elementAt(i).seleccionada){

                    ciudad = vectorCiudades.elementAt(i).nombreCiudad;

                    tenis = true;

                    Intent intent = new Intent (c,ServicioNotificacion.class);
                    c.startService(intent);

                }
            }
        } else {
            tenis = false;
        }

    }


    public void borrarVectorCiudades(Activity a, Context c){

        progress = ProgressDialog.show(c,"Cargando", "Borrando ciudades", true);

        ThreadBorrar hilo = new ThreadBorrar(a,c);
        hilo.start();


    }


    public class ThreadBorrar extends Thread {

        Activity a;
        Context c;

        public ThreadBorrar(Activity a,Context c){
            this.a = a;
            this.c = c;
        }

        @Override
        public void run() {

            for (int i=vectorCiudades.size()-1;i>=0;i--){
                borrar(i);
            }

            a.runOnUiThread(new Runnable(){

                @Override public void run(){
                    notifyDataSetChanged();
                    almacen.actualizarVectorCiudades(AdaptadorCiudades.this);

                    AlertDialog.Builder builder = new AlertDialog.Builder(c);
                    builder.setMessage("Ciudades borradas correctamente");
                    builder.setPositiveButton(android.R.string.ok, null);
                    builder.create().show();
                    progress.dismiss();
                }
            });
        }
    }
}