## This is really the Controller part of MVC. Yes this is weird. Very weird.
from django.shortcuts import render
from django.utils import timezone
from django.http import HttpResponseRedirect, HttpResponse
from .forms import *
from .models import *
from linkedin.linkedin import (LinkedInAuthentication, LinkedInApplication,
                               PERMISSIONS)
from django.conf import settings
from .scrapers import *
from .text_mine import get_most_occured, get_match_percentage, stemmed_top_user_words
import wikipedia

# Create your views here.
def home(request):
    if request.session.get('linkedin_access_token', None):
        return HttpResponseRedirect('/search/')
    else:
        return render(request, 'munchee/home.html', {})

def logout(request):
    if request.session.get('linkedin_access_token'):
        del request.session['linkedin_access_token']
    if request.session.get('linkedin_userid'):
        del request.session['linkedin_userid']
    return HttpResponseRedirect("/")

def search_form(request):
    if request.session.get('linkedin_access_token', None):
        form = CompanyForm()
        return render(request, 'munchee/search.html', {})
    else:
        return HttpResponseRedirect("/")

def search(request):
    debug = ""
    if request.method == 'POST':
        form = CompanyForm(request.POST)
        if form.is_valid():
            company_dbs = []
            #return HttpResponse("Is valid \n" + str(form.cleaned_data.keys()))
            companies = [x.strip() for x in form.cleaned_data['companies'].replace('\n',',').split(',')]
            keywords = [x.strip() for x in form.cleaned_data['keywords'].replace('\n',',').split(',')]

            # remove duplicates
            companies = list(set(companies))
            keywords = list(set(keywords))
            user_db = Profile.objects.get(user_id=request.session['linkedin_userid'])
            user_text = ' '.join([user_db.summary, user_db.industry, user_db.location_name])
            user_text = ' '.join(keywords) + ' ' + user_text
            user_words = stemmed_top_user_words(user_text,10)

            for company in companies:
                do_not_modify = False
                ## start hitting multiple sites
                # LinkedIn
                data = scrape_linkedin_company(request.session['linkedin_access_token'], company)
                print(data)
                debug += str(data)
                try:
                    if data['companies']['_total'] == 0:
                        continue
                except KeyError:
                    pass
                # gonna take the first one lol
                try:
                    the_company = data['companies']['values'][0]
                    company_id = the_company['id']
                except:
                    return HttpResponseRedirectttpResponse(debug)


                # get the company entry in database, if any
                try:
                    company_db = Company.objects.get(id=company_id)
                    if company_db.last_updated - timezone.now() < timezone.timedelta(days=1):
                        do_not_modify = True
                except Company.DoesNotExist:
                    company_db = Company()

                name = the_company['name']
                website = the_company.get('websiteUrl', "")
                raw_locations = the_company.get('locations', {"_total": 0})
                if raw_locations['_total'] == 0:
                    locations = []
                else:
                    locations = [x['address'].get('city', "") for x in raw_locations['values']]
                ticker = the_company.get('ticker', "")
                description = the_company.get('description', "")
                logo_url = the_company.get('logoUrl', "")

                # Google
                news = '' # temporary empty

                if not do_not_modify:
                    company_db.id = company_id
                    company_db.name = name
                    company_db.website = website
                    company_db.locations = ','.join(locations)
                    company_db.ticker = ticker
                    company_db.description = description
                    company_db.logo_url = logo_url
                    company_db.news = news

                    company_db.save()

                company_dbs.append(company_db)

                # text mining/analysis
                
                try:
                    company_text = [company_db.locations,description,news]
                    company_text.append(str(wikipedia.page(company_db.name+', company').summary))
                except:
                    pass
                finally:
                    company_text = ' '.join(company_text)
                company_db.score = get_match_percentage(company_text,user_words)
                company_db.freq_words = ', '.join([x[0] for x in get_most_occured(company_text, 20)])
            #debug = "" # clear debug because too lazy to remove
            return render(request, "munchee/results.html", {"companies": company_dbs, "debug": debug})
            #return HttpResponse(debug + "<br><br><br>")

    elif request.session.get('linkedin_access_token', None):
        return HttpResponseRedirect("/search/")
    else:
        return HttpResponseRedirect("/")

def oauth_login_start(request):
    authentication = LinkedInAuthentication(settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_KEY,
                                            settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_SECRET,
                                            settings.RETURN_URL,
                                            [PERMISSIONS.BASIC_PROFILE, PERMISSIONS.EMAIL_ADDRESS])
    return HttpResponseRedirect(authentication.authorization_url)

def oauth_callback(request):
    authentication = LinkedInAuthentication(settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_KEY,
                                            settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_SECRET,
                                            settings.RETURN_URL,
                                            [PERMISSIONS.BASIC_PROFILE, PERMISSIONS.EMAIL_ADDRESS])
    if request.method == 'GET':
        form = OAuthCallbackForm(request.GET)
        if form.is_valid():
            """cleaned_code = form.cleaned_data['code']
            cleaned_state = form.cleaned_data['state']
            return HttpResponse("Code: " + cleaned_code + "\nState: " + cleaned_state)"""
            authentication.authorization_code = form.cleaned_data['code']
            token = authentication.get_access_token()

            # store access token in session
            request.session['linkedin_access_token'] = token

            application = LinkedInApplication(token=token)

            # get profile from LinkedIn
            profile_data = application.get_profile(selectors=['id', 'first-name', 'last-name', 'location', 'industry',
                                                              'email-address', 'summary'])

            # Try to get summary data
            try:
                summary = profile_data['summary']
            except KeyError:
                summary = ''

            # Get existing profile in database
            try:
                profile_db = Profile.objects.get(user_id=profile_data['id'])

                profile_db.user_id=profile_data['id']
                profile_db.first_name=profile_data['firstName']
                profile_db.last_name=profile_data['lastName']
                profile_db.email=profile_data['emailAddress']
                profile_db.summary=summary
                profile_db.industry=profile_data['industry']
                profile_db.location_name=profile_data['location']['name']

            except Profile.DoesNotExist:
                profile_db = Profile(user_id=profile_data['id'], first_name=profile_data['firstName'],
                                 last_name=profile_data['lastName'], email=profile_data['emailAddress'],
                                 summary=summary, industry=profile_data['industry'],
                                 location_name=profile_data['location']['name'])

            # store profile
            profile_db.save()

            request.session['linkedin_userid'] = profile_data['id']

            # redirect to search page
            return HttpResponseRedirect("/search/")

            #return HttpResponse(str(profile_data))

            # do stuff with application and then return list. Possibly store application in session data

## This is really the Controller part of MVC. Yes this is weird. Very weird.
from django.shortcuts import render
from django.utils import timezone
from django.http import HttpResponseRedirect, HttpResponse
from .forms import *
from .models import *
from linkedin.linkedin import (LinkedInAuthentication, LinkedInApplication,
                               PERMISSIONS)
from django.conf import settings
from .scrapers import *
from .text_mine import get_most_occured, get_match_percentage, stemmed_top_user_words
import wikipedia

# Create your views here.
def home(request):
    if request.session.get('linkedin_access_token', None):
        return HttpResponseRedirect('/search/')
    else:
        return render(request, 'munchee/home.html', {})

def logout(request):
    if request.session.get('linkedin_access_token'):
        del request.session['linkedin_access_token']
    if request.session.get('linkedin_userid'):
        del request.session['linkedin_userid']
    return HttpResponseRedirect("/")

def search_form(request):
    if request.session.get('linkedin_access_token', None):
        form = CompanyForm()
        return render(request, 'munchee/search.html', {})
    else:
        return HttpResponseRedirect("/")

def search(request):
    debug = ""
    if request.method == 'POST':
        form = CompanyForm(request.POST)
        if form.is_valid():
            company_dbs = []
            #return HttpResponse("Is valid \n" + str(form.cleaned_data.keys()))
            companies = [x.strip() for x in form.cleaned_data['companies'].replace('\n',',').split(',')]
            keywords = [x.strip() for x in form.cleaned_data['keywords'].replace('\n',',').split(',')]

            # remove duplicates
            companies = list(set(companies))
            keywords = list(set(keywords))
            user_db = Profile.objects.get(user_id=request.session['linkedin_userid'])
            user_text = ' '.join([user_db.summary, user_db.industry, user_db.location_name])
            user_text = ' '.join(keywords) + ' ' + user_text
            user_words = stemmed_top_user_words(user_text,10)

            for company in companies:
                do_not_modify = False
                ## start hitting multiple sites
                # LinkedIn
                data = scrape_linkedin_company(request.session['linkedin_access_token'], company)
                print(data)
                debug += str(data)
                try:
                    if data['companies']['_total'] == 0:
                        continue
                except KeyError:
                    pass
                # gonna take the first one lol
                try:
                    the_company = data['companies']['values'][0]
                    company_id = the_company['id']
                except:
                    return HttpResponseRedirectttpResponse(debug)


                # get the company entry in database, if any
                try:
                    company_db = Company.objects.get(id=company_id)
                    if company_db.last_updated - timezone.now() < timezone.timedelta(days=1):
                        do_not_modify = True
                except Company.DoesNotExist:
                    company_db = Company()

                name = the_company['name']
                website = the_company.get('websiteUrl', "")
                raw_locations = the_company.get('locations', {"_total": 0})
                if raw_locations['_total'] == 0:
                    locations = []
                else:
                    locations = [x['address'].get('city', "") for x in raw_locations['values']]
                ticker = the_company.get('ticker', "")
                description = the_company.get('description', "")
                logo_url = the_company.get('logoUrl', "")

                # Google
                news = '' # temporary empty

                if not do_not_modify:
                    company_db.id = company_id
                    company_db.name = name
                    company_db.website = website
                    company_db.locations = ','.join(locations)
                    company_db.ticker = ticker
                    company_db.description = description
                    company_db.logo_url = logo_url
                    company_db.news = news

                    company_db.save()

                company_dbs.append(company_db)

                # text mining/analysis
                
                try:
                    company_text = [company_db.locations,description,news]
                    company_text.append(str(wikipedia.page(company_db.name+', company').summary))
                except:
                    pass
                finally:
                    company_text = ' '.join(company_text)
                company_db.score = get_match_percentage(company_text,user_words)
                company_db.freq_words = ', '.join([x[0] for x in get_most_occured(company_text, 20)])
            #debug = "" # clear debug because too lazy to remove
            return render(request, "munchee/results.html", {"companies": company_dbs, "debug": debug})
            #return HttpResponse(debug + "<br><br><br>")

    elif request.session.get('linkedin_access_token', None):
        return HttpResponseRedirect("/search/")
    else:
        return HttpResponseRedirect("/")

def oauth_login_start(request):
    authentication = LinkedInAuthentication(settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_KEY,
                                            settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_SECRET,
                                            settings.RETURN_URL,
                                            [PERMISSIONS.BASIC_PROFILE, PERMISSIONS.EMAIL_ADDRESS])
    return HttpResponseRedirect(authentication.authorization_url)

def oauth_callback(request):
    authentication = LinkedInAuthentication(settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_KEY,
                                            settings.SOCIAL_AUTH_LINKEDIN_OAUTH2_SECRET,
                                            settings.RETURN_URL,
                                            [PERMISSIONS.BASIC_PROFILE, PERMISSIONS.EMAIL_ADDRESS])
    if request.method == 'GET':
        form = OAuthCallbackForm(request.GET)
        if form.is_valid():
            """cleaned_code = form.cleaned_data['code']
            cleaned_state = form.cleaned_data['state']
            return HttpResponse("Code: " + cleaned_code + "\nState: " + cleaned_state)"""
            authentication.authorization_code = form.cleaned_data['code']
            token = authentication.get_access_token()

            # store access token in session
            request.session['linkedin_access_token'] = token

            application = LinkedInApplication(token=token)

            # get profile from LinkedIn
            profile_data = application.get_profile(selectors=['id', 'first-name', 'last-name', 'location', 'industry',
                                                              'email-address', 'summary'])

            # Try to get summary data
            try:
                summary = profile_data['summary']
            except KeyError:
                summary = ''

            # Get existing profile in database
            try:
                profile_db = Profile.objects.get(user_id=profile_data['id'])

                profile_db.user_id=profile_data['id']
                profile_db.first_name=profile_data['firstName']
                profile_db.last_name=profile_data['lastName']
                profile_db.email=profile_data['emailAddress']
                profile_db.summary=summary
                profile_db.industry=profile_data['industry']
                profile_db.location_name=profile_data['location']['name']

            except Profile.DoesNotExist:
                profile_db = Profile(user_id=profile_data['id'], first_name=profile_data['firstName'],
                                 last_name=profile_data['lastName'], email=profile_data['emailAddress'],
                                 summary=summary, industry=profile_data['industry'],
                                 location_name=profile_data['location']['name'])

            # store profile
            profile_db.save()

            request.session['linkedin_userid'] = profile_data['id']

            # redirect to search page
            return HttpResponseRedirect("/search/")

            #return HttpResponse(str(profile_data))

            # do stuff with application and then return list. Possibly store application in session data

## This is really the Controller part of MVC. Yes this is weird. Very weird. # Create your views here. #return HttpResponse("Is valid \n" + str(form.cleaned_data.keys())) # remove duplicates ## start hitting multiple sites # LinkedIn # gonna take the first one lol # get the company entry in database, if any # Google # temporary empty # text mining/analysis #debug = "" # clear debug because too lazy to remove #return HttpResponse(debug + "<br><br><br>") cleaned_code = form.cleaned_data['code']             cleaned_state = form.cleaned_data['state']             return HttpResponse("Code: " + cleaned_code + "\nState: " + cleaned_state) # store access token in session # get profile from LinkedIn # Try to get summary data # Get existing profile in database # store profile # redirect to search page #return HttpResponse(str(profile_data)) # do stuff with application and then return list. Possibly store application in session data