package de.apps4ics.mountainnavigation;

import android.app.Activity;
import android.location.Address;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;

import org.osmdroid.bonuspack.location.GeocoderNominatim;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;

import de.apps4ics.mountainnavigation.handlers.WeatherHandler;

/**
 * This file is part of MountainNavigation.
 *
 * MountainNavigation 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.
 *
 * MountainNavigation 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 MountainNavigation.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @copyright Copyright (c) 2016 Vinzenz Rosenkanz <vinzenz.rosenkranz@gmail.com>
 *
 * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
 */
public class DownloadActivity extends Activity implements OnSingleWeatherRetrieved, OnWeatherRetrieved {
    LinearLayout dayLayout;
    SeekBar dayPicker;
    TextView dayDisplay;
    EditText customLocationInput;
    Button startDownload;
    int nrOfForecastDays;
    String currentSelected;
    boolean customLocationFound;
    Location customLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download);
        customLocationFound = false;

        dayLayout = (LinearLayout) findViewById(R.id.forecastNrOfDaysLayout);
        dayPicker = (SeekBar) findViewById(R.id.forecastNrOfDaysSeek);
        dayDisplay = (TextView) findViewById(R.id.forecastNrOfDays);
        customLocationInput = (EditText) findViewById(R.id.download_custom_location);
        nrOfForecastDays = SettingsActivity.getDaysForecastFromPrefs();
        dayPicker.setProgress(nrOfForecastDays - WeatherHandler.MIN_DAYS_FORECAST);
        dayDisplay.setText(getResources().getQuantityString(R.plurals.number_of_days_plurals, nrOfForecastDays, nrOfForecastDays));
        dayPicker.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                nrOfForecastDays = progress + WeatherHandler.MIN_DAYS_FORECAST;
                dayDisplay.setText(getResources().getQuantityString(R.plurals.number_of_days_plurals, nrOfForecastDays, nrOfForecastDays));
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
        customLocationInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if(actionId == EditorInfo.IME_ACTION_DONE) {
                    List<Address> addresses = null;
                    try {
                        addresses = new GeocodingTask().execute(new String[]{ customLocationInput.getText().toString() }).get();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                    if(addresses.size() == 0) {
                        customLocationFound = false;
                        customLocation = null;
                        //TODO translation
                        InformDialog informDialog = new InformDialog("Could not find location", "The entered location could not be found. Try some bigger city near your location.");
                        informDialog.show(getFragmentManager(), "Inform Dialog");
                    } else {
                        Address address = addresses.get(0);
                        MainActivity.Toaster(address.getLocality() + " found in " + address.getCountryName(), DownloadActivity.this);
                        customLocation = new Location("");
                        customLocation.setLatitude(address.getLatitude());
                        customLocation.setLongitude(address.getLongitude());
                        customLocationFound = true;
                    }
                    return true;
                }
                return false;
            }
        });
        customLocationInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                customLocationFound = false;
                customLocation = null;
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        startDownload = (Button) findViewById(R.id.download_start);
        startDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WeatherHandler weatherHandler = MainActivity.getWeatherHandler();
                Location l = null;
                if(customLocationInput.getText().length() == 0) {
                    l = MainActivity.getLocation();
                    if(l == null) {
                        InformDialog informDialog = new InformDialog(getString(R.string.inform_title), getString(R.string.inform_gps_pos_not_found));
                        informDialog.show(getFragmentManager(), "Inform Dialog");
                        return;
                    }
                } else if(!customLocationFound) {
                    //TODO translation
                    InformDialog informDialog = new InformDialog("Custom location not found", "Please enter a proper city name or empty the search field to use current location.");
                    informDialog.show(getFragmentManager(), "Inform Dialog");
                    return;
                } else {
                    l = customLocation;
                }

                Log.d(MainActivity.TAG, "currentSelected: " + currentSelected);
                Log.d(MainActivity.TAG, "nrOfForecastDays: " + nrOfForecastDays);

                if(currentSelected.equals(getString(R.string.download_forecast_key))) {
                    weatherHandler.getForecast(l, nrOfForecastDays, DownloadActivity.this);
                } else if(currentSelected.equals(getString(R.string.download_current_key))) {
                    weatherHandler.getCurrentWeather(l, DownloadActivity.this);
                } else if(currentSelected.equals(getString(R.string.download_day_key))) {
                    //TODO
                }
            }
        });

        Spinner dlCategory = (Spinner) findViewById(R.id.downloadCategory);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.download_categories, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        dlCategory.setAdapter(adapter);
        dlCategory.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String key = currentSelected = getResources().getStringArray(R.array.download_categories_keys)[position];
                if(key.equals(getString(R.string.download_forecast_key))) {
                    dayLayout.setVisibility(View.VISIBLE);
                } else {
                    dayLayout.setVisibility(View.INVISIBLE);
                }
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
    }

    @Override
    public MyWeather postRetrieve(MyWeather weather) {
        MainActivity.Toaster("Got current weather for current/stated location", this);
        Log.d(MainActivity.TAG, weather.getCity() + " (" + MainActivity.df_full.format(new Date(weather.getTimestamp())) + ")");
        return null;
    }

    @Override
    public List<MyWeather> postRetrieve(List<MyWeather> weathers) {
        if(weathers.size() == 0) {
            MainActivity.Toaster("No forecasts found for this location!", this);
        } else {
            MainActivity.Toaster(weathers.size() + " forecasts found and added!", this);
        }
        for(MyWeather mw : weathers) {
            Log.d(MainActivity.TAG, mw.getCity() + " (" + MainActivity.df_full.format(new Date(mw.getTimestamp()*1000)) + ")");
        }
        return null;
    }

    private class GeocodingTask extends AsyncTask<String, Void, List<Address>> {
        @Override
        protected List<Address> doInBackground(String... params) {
            String locationName = params[0];
            GeocoderNominatim geocoder = new GeocoderNominatim(DownloadActivity.this, "");
            try {
                List<Address> addresses = geocoder.getFromLocationName(locationName, 5);
                return addresses;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}
