/*
 * GetTripsTask.java
 * AsyncTask that loads the trip list of the requested user
 */

package com.cc.infosur.main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.cc.infosur.R;
import com.cc.infosur.greendao.DaoMaster;
import com.cc.infosur.greendao.DaoSession;
import com.cc.infosur.greendao.DaoMaster.DevOpenHelper;
import com.cc.infosur.greendao.TravellerInfo;
import com.cc.infosur.greendao.TravellerInfoDao;
import com.cc.infosur.greendao.TripInfo;
import com.cc.infosur.greendao.TripInfoDao;


import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;

public class GetTripsTask extends AsyncTask<Void, Void, Integer> {

	private Context context;
	private String user;
	private String password;
	private Integer travellerId;
    private String emailInsert;
    private String passwordInsert;

	// Database variables
	private SQLiteDatabase db;
	private DevOpenHelper helper;
	private DaoSession daoSession;
	private DaoMaster daoMaster;
	private TravellerInfoDao travellerInfoDao;
	private TripInfoDao tripInfoDao;

	Handler updateBarHandler;

    /**
     * Constructor
     * @param activity
     * @param user
     * @param password
     */
	public GetTripsTask(LoadActivity activity, String user, String password) {
		super();
		context = activity;
		this.user = user;
		this.password = password;
	}

    /**
     * Function onPreExecute() - AsyncTask 1 / 3
     */
    ProgressDialog pDialog;
	protected void onPreExecute() {
		updateBarHandler = new Handler();
		pDialog = new ProgressDialog(context);
        pDialog.setTitle(context.getResources().getString(R.string.download));
		pDialog.setMessage(context.getResources().getString(R.string.listing_event));
		pDialog.setProgressStyle(pDialog.STYLE_HORIZONTAL);
		pDialog.setCancelable(false);
		pDialog.setCanceledOnTouchOutside(false);
		pDialog.show();
	}

    /**
     * Function doInBackground() - AsyncTask 2 / 3
     */
	@Override
	protected Integer doInBackground(Void... params) {
		String jsonStr = null;

		// Prepare db
		helper = new DaoMaster.DevOpenHelper(context, "tripdb", null);
		db = helper.getWritableDatabase();
		daoMaster = new DaoMaster(db);
		daoSession = daoMaster.newSession();
		travellerInfoDao = daoSession.getTravellerInfoDao();
		tripInfoDao = daoSession.getTripInfoDao();

		// Delete db
		travellerInfoDao.deleteAll();
		tripInfoDao.deleteAll();

		// Call to the SENSA API with the user data
		
		// Create a new HttpClient and Post Header
		HttpClient httpclient = new DefaultHttpClient();

        // For Testing - Add the ID of the trip after /list/ to display only one trip [Ex : /list/1970/] )
		//HttpPost httppost = new HttpPost("http://sensa-demo.tripalacarte.com/api/trips/list/1863");
        HttpPost httppost = new HttpPost("http://sensa-prod3.tripalacarte.com/api/trips/list/");

        //HttpPost httppost = new HttpPost("http://sensa-demo.tripalacarte.com/api/trips/list/");


        try {
			// Add post data
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
			nameValuePairs.add(new BasicNameValuePair("email", user));
			nameValuePairs.add(new BasicNameValuePair("password", password));
			httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
			Log.e("HTTP POST ",httppost.getMethod());
			// Execute HTTP Request
			HttpResponse response = httpclient.execute(httppost);

            while(response.getStatusLine().getStatusCode()==408){
                response = httpclient.execute(httppost);
            }


            // Get the string
			HttpEntity entity = response.getEntity();

			if (entity != null) {

				// A Simple JSON Response Read
				InputStream instream = entity.getContent();
				jsonStr = convertStreamToString(instream);
				// now you have the string representation of the HTML request
				instream.close();
				Log.i("JSON", jsonStr);
			}

		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace() ;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace() ;
		}

		// Get the json with the available trips of the user, get them and put into the database
		try {

            System.out.println(" SENSA :: GetTripsTask :: jsonStr :: " + jsonStr);
            // Convert into JSONObject
			JSONObject jsonObject = new JSONObject(jsonStr);

            System.out.println(" SENSA :: GetTripsTask :: jsonObject :: " + jsonObject);

            // Get the id result
			int result = jsonObject.getInt("result");
			System.out.print("######## RESULT :"+result);

            // If the id result if different to 0 = ERROR -> Return result (onPostExecute()
			if (result != 0) return result;

			JSONObject messageObject = jsonObject.getJSONObject("message");

			travellerId = messageObject.getInt("travellerid");
			TravellerInfo travellerInfo = new TravellerInfo();
			travellerInfo.setId(travellerId.longValue());

            emailInsert = messageObject.getString("email");
            travellerInfo.setEmail(emailInsert.toString());
            passwordInsert = messageObject.getString("password");
            travellerInfo.setPassword(passwordInsert.toString());

            System.out.println(" SENSA :: GetTripsTask :: email = " + emailInsert + " :: password = " + passwordInsert );

            JSONArray tripsArray = messageObject.getJSONArray("trips");
			
			// Progress Dialog - Length Array
			pDialog.setMax(tripsArray.length());
			
			for (int i = 0; i < tripsArray.length(); i++) {

				JSONObject trip = tripsArray.getJSONObject(i);
				TripInfo tripInfo = new TripInfo();
				Integer tripInfoId = trip.getInt("tripid");
				tripInfo.setId(tripInfoId.longValue());
				
				// Progress Dialog - Loading 
				pDialog.setProgress(i+1);
				
				if (getTripInfo(tripInfo)) {
					tripInfo.setUserInfoId(travellerId);
					tripInfoDao.insert(tripInfo);
				}
			}

			travellerInfoDao.insert(travellerInfo);

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return 0;
	}



    /**
     * Function onPostExecute() - AsyncTask 3 / 3
     */
	protected void onPostExecute(Integer result) {
		
		pDialog.dismiss();

        // Correct Login and Password
		if (result == 0) {

            // But this user/traveler has not booked a trip yet
			if (tripInfoDao.loadAll().size() == 0) {
				new AlertDialog.Builder(context)
						.setTitle(context.getResources().getString(R.string.success_login))
                        .setMessage(context.getResources().getString(R.string.no_event))
						.setNegativeButton("Ok",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int which) {
										dialog.dismiss();
									}
								}).show();

            // Show list trips of the user/traveler concerned
			} else {
			    LoadActivity loadActivity = (LoadActivity) context;
				loadActivity.showTrips(travellerId);
			}

		} else if(result == 16) {
			new AlertDialog.Builder(context)
					.setTitle(context.getResources().getString(R.string.missing_field))
                    .setMessage(context.getResources().getString(R.string.fill_field))
					.setNegativeButton("Ok",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int which) {
									dialog.dismiss();
								}
							}).show();

        } else if(result == 17) {
            new AlertDialog.Builder(context)
                    .setTitle("Activation Account ")
                    .setMessage("Please make sure your account is activated")
                    .setNegativeButton("Ok",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                                    int which) {
                                    dialog.dismiss();
                                }
                            }).show();

		} else {
            new AlertDialog.Builder(context)
                    .setTitle(context.getResources().getString(R.string.error_login))
                    .setMessage(context.getResources().getString(R.string.bad_pseudo_password))
                    .setNegativeButton("OK",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                                    int which) {
                                    dialog.dismiss();
                                }
                            }).show();
        }
	}



    /**
     * Function getTripInfo()
     * @param tripInfo
     * @return
     *
     * Download the json of each trip and store the data
     */
	private boolean getTripInfo(TripInfo tripInfo) {
		// Create a new HttpClient and Post Header
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(
				"http://sensa-prod3.tripalacarte.com/api/trips/" + travellerId
						+ "/" + tripInfo.getId() + "/mobile");



		Log.i("TRIPS", "http://sensa-prod3.tripalacarte.com/api/trips/"
				+ travellerId + "/" + tripInfo.getId() + "/mobile");

		try {
			// Execute HTTP Request
			HttpResponse response = httpclient.execute(httpget);

			// Get the string
			HttpEntity entity = response.getEntity();

			if (entity != null) {
				// A Simple JSON Response Read
				InputStream instream = entity.getContent();
				tripInfo.setJson(convertStreamToString(instream));
				instream.close();
			}

		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
		} catch (IOException e) {
			// TODO Auto-generated catch block
		}

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

		JSONObject jsonObject;
		try {
			jsonObject = new JSONObject(tripInfo.getJson());
			JSONObject tripObject = jsonObject.getJSONObject("message");
			tripInfo.setName(tripObject.getString("name"));
			
			// CALENDAR FOR TESTING - 06102014
			Calendar c = Calendar.getInstance();
			// CURRENT DATE FOR DATEFROM
			String dateFrom = format.format(c.getTime());
			// ADD ONE DATE FOR DATETO
			c.add(Calendar.DATE, 1);
			String dateTo = format.format(c.getTime());
			
			if( dateFrom != null || dateFrom != "null" || !dateFrom.isEmpty() ) {
				tripInfo.setDateFrom(format.parse(dateFrom));
			}
			if( dateTo != null || dateTo != "null" || !dateTo.isEmpty() ) {
				tripInfo.setDateTo(format.parse(dateTo));
			}		
			
			tripInfo.setDateFrom(format.parse(tripObject.getString("dateFrom")));
			tripInfo.setDateTo(format.parse(tripObject.getString("dateTo")));
		} catch (JSONException e) {
			e.printStackTrace();
			return false;
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}

		return true;
	}



    /**
     * Function convertStreamToString()
     * @param is
     * @return
     */
	private static String convertStreamToString(InputStream is) {
		
		StringBuilder sb = new StringBuilder();
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					is, "UTF8"));

			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

}
