#!/usr/bin/env Python
"""Retrieve Tweets, embeddings, and persist in the database."""
import tweepy
import spacy
from decouple import config

from .models import DB, Tweet, User


TWITTER_AUTH = tweepy.OAuthHandler(
    config('TWITTER_API_KEY'),
    config('TWITTER_API_SECRET')
)

TWITTER_AUTH.set_access_token(
    config('TWITTER_ACCESS_TOKEN'),
    config('TWITTER_ACCESS_TOKEN_SECRET')
)

TWITTER = tweepy.API(TWITTER_AUTH)


def add_or_update_user(username):
    """Add or update a user and their Tweets, error if not a Twitter user."""
    try:
        nlp = spacy.load('en_core_web_lg')
        twitter_user = TWITTER.get_user(username)
        db_user = (User.query.get(twitter_user.id) or
                   User(id=twitter_user.id, name=username))
        # DB.session.add(db_user)
        # We want as many recent non-retweet/reply statuses as we can get
        # 200 is a Twitter API limit, we'll usually see less due to exclusions
        tweets = twitter_user.timeline(
            count=200, exclude_replies=True, include_rts=False,
            tweet_mode='extended', since_id=db_user.newest_tweet_id)
        if tweets:
            db_user.newest_tweet_id = tweets[0].id
        for tweet in tweets:
            text = tweet.full_text
            embedding = list(nlp(text).vector)
            db_tweet = Tweet(id=tweet.id, text=text,
                             embedding=embedding)
            db_user.tweets.append(db_tweet)
            DB.session.add(db_user)
    except Exception as e:
        print(f'Error processing {username}: {e}')
        raise e
    else:
        DB.session.commit()


def update_all_users():
    """Update all existing users."""
    for user in User.query.all():
        add_or_update_user(user.name)
