#!/usr/bin/env python

import json
import twilio
import argparse
import requests
import threading
from geopy.distance import vincenty
from twilio.rest import TwilioRestClient

import pokemonalerts.data

CELL_PHONE_NUMBER = None
TWILIO_PHONE_NUMBER = None
TWILIO_ACCOUNT_SID = None
TWILIO_AUTH_TOKEN = None


def find_pokemon(lat, lng, distance, ignore, include):
    found_pokemon_ids = set()

    if ignore:
        ignore = [int(x.strip()) for x in ignore.split(',')]

    if include:
        include = [int(x.strip()) for x in include.split(',')]

    url = "https://pokevision.com/map/data/{0}/{1}".format(lat, lng)
    r = requests.get(url)
    results = json.loads(r.text)

    for result in results["pokemon"]:
        dist = vincenty((lat, lng), (result["latitude"], result["longitude"])).meters
        if dist < distance:
            if ignore and result["pokemonId"] not in ignore:
                found_pokemon_ids.add(result["pokemonId"])
            elif include and result["pokemonId"] in include:
                found_pokemon_ids.add(result["pokemonId"])
            elif not ignore and not include:
                found_pokemon_ids.add(result["pokemonId"])

    if found_pokemon_ids:
        send_alerts(found_pokemon_ids, distance)

def send_alerts(pokemon_ids, distance):

    #for id in pokemon_ids:
    #    print("{0} ({1})".format(pokemonalerts.data.pokemon[id].capitalize(), id))

    message = ""

    if len(pokemon_ids) > 1:
        i = 0
        for id in pokemon_ids:
            if i == 0:
                message = "{0} ({1})".format(pokemonalerts.data.pokemon[id].capitalize(), id)
            if i < len(pokemon_ids):
                message += ", {0} ({1})".format(pokemonalerts.data.pokemon[id].capitalize(), id)
            if i == len(pokemon_ids):
                message += " and {0} ({1})".format(pokemonalerts.data.pokemon[id].capitalize(), id)
            i += 1
        message += " are within {0} meters of your location.".format(distance)
    else:
        pokemon_ids = list(pokemon_ids)
        message = "{0} ({1}) is within {2} meters of your location.".format(pokemonalerts.data.pokemon[pokemon_ids[0]].capitalize(), pokemon_ids[0], distance)

    if CELL_PHONE_NUMBER and TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN and TWILIO_PHONE_NUMBER:
        print("Sending SMS...")
        client = TwilioRestClient(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)
        client.messages.create(to=CELL_PHONE_NUMBER, from_=TWILIO_PHONE_NUMBER, body=message)

    print(message)

def search(lat, lng, distance, ignore, include, time):
    find_pokemon(lat, lng, distance, ignore, include)
    threading.Timer(int(time)*60, search, args=(lat, lng, distance, ignore, include, time)).start()

def main():

    parser = argparse.ArgumentParser()

    parser.add_argument("-lat", "--latitude", help="Latitude of the Search Location")
    parser.add_argument("-lng", "--longitude", help="Longitude of the Search Location")
    parser.add_argument("-d", "--distance", help="Distance to use for Pokemon search (in meters)")
    parser.add_argument("-i", "--ignore", help="CSV of Pokemon id's to ignore")
    parser.add_argument("-in", "--include", help="CSV of Pokemon id's to include")
    parser.add_argument("-t", "--time", help="Time interval in minutes to check for Pokemon (1 minute minimum, 5 minute default)")
    parser.add_argument("--twilio", action='store_true', help="Script will prompt for Twilio credentials and Phone numbers so it can send you SMS alerts")

    args = parser.parse_args()

    if args.ignore and args.include:
        raise Exception("You cannot use both --ignore and --include arguments")

    if not args.distance:
        args.distance = 100

    if not args.time:
        args.time = 5
    elif int(args.time) < 1:
        raise Exception("You must entire a time greater than 1 minute")

    if args.twilio:
        CELL_PHONE_NUMBER = input("Cell Phone Number (to): ")
        TWILIO_PHONE_NUMBER = input("Twilio Phone Number (from): ")
        TWILIO_ACCOUNT_SID = input("Twilio Account SID (Optional): ")
        TWILIO_AUTH_TOKEN = input("Twilio Auth Token (Optional): ")

    search(args.latitude, args.longitude, int(args.distance), args.ignore, args.include, args.time)

main()
