# issue/views_admin.py
# Brought to you by We Vote. Be good.
# -*- coding: UTF-8 -*-

from .controllers import *
from .models import ALPHABETICAL_ASCENDING, Issue, OrganizationLinkToIssue
from admin_tools.views import redirect_to_sign_in_page
from config.base import get_environment_variable
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.messages import get_messages
from django.shortcuts import render
from election.controllers import retrieve_election_id_list_by_year_list, retrieve_upcoming_election_id_list
from election.models import ElectionManager
from exception.models import handle_record_found_more_than_one_exception, handle_exception
from image.controllers import cache_issue_image_master, cache_resized_image_locally, delete_cached_images_for_issue
from image.models import WeVoteImageManager
from organization.models import INDIVIDUAL, OrganizationManager, OrganizationListManager
from voter.models import fetch_api_voter_from_request, voter_has_authority
from voter_guide.models import VoterGuideListManager
import wevote_functions.admin
from wevote_functions.functions import convert_to_int, positive_value_exists, get_voter_device_id, STATE_CODE_MAP
from django.http import HttpResponse
import json

ORGANIZATION_LINK_TO_ISSUE_SYNC_URL = \
    get_environment_variable("ORGANIZATION_LINK_TO_ISSUE_SYNC_URL")  # organizationLinkToIssueSyncOut
ISSUES_SYNC_URL = get_environment_variable("ISSUES_SYNC_URL")  # issuesSyncOut
WE_VOTE_SERVER_ROOT_URL = get_environment_variable("WE_VOTE_SERVER_ROOT_URL")

logger = wevote_functions.admin.get_logger(__name__)


# This page does not need to be protected.
def issues_sync_out_view(request):  # issuesSyncOut
    issue_search = request.GET.get('issue_search', '')

    try:
        issue_list = Issue.objects.all()
        filters = []
        if positive_value_exists(issue_search):
            new_filter = Q(issue_name__icontains=issue_search)
            filters.append(new_filter)

            new_filter = Q(issue_description__icontains=issue_search)
            filters.append(new_filter)

            new_filter = Q(we_vote_id__iexact=issue_search)
            filters.append(new_filter)

            # Add the first query
            if len(filters):
                final_filters = filters.pop()

                # ...and "OR" the remaining items in the list
                for item in filters:
                    final_filters |= item

                issue_list = issue_list.filter(final_filters)

        issue_list_dict = issue_list.values('we_vote_id', 'considered_left', 'considered_right', 'hide_issue',
                                            'issue_name', 'issue_description', 'issue_icon_local_path',
                                            'issue_followers_count', 'linked_organization_count',
                                            'we_vote_hosted_image_url_large', 'we_vote_hosted_image_url_medium',
                                            'we_vote_hosted_image_url_tiny')
        if issue_list_dict:
            issue_list_json = list(issue_list_dict)
            return HttpResponse(json.dumps(issue_list_json), content_type='application/json')
    except Exception as e:
        pass

    json_data = {
        'success': False,
        'status': 'ISSUES_LIST_MISSING'
    }
    return HttpResponse(json.dumps(json_data), content_type='application/json')


def issue_descriptions_retrieve_view(request):  # issueDescriptionsRetrieve
    http_response = issue_
descriptions_retrieve_for_api()
    return http_response


def issues_followed_retrieve_view(request):  # issuesFollowedRetrie
ve
    voter_device_id = get_voter_device_id(request)  # We standardize how we take in the voter_device_id
    http_response = issues_followed_retrieve_for_api(voter_device_id)
    return http_response


def issues_retrieve_view(request):  # issuesRetrieve  # Deprecated
    voter_device_id = get_voter_device_id(request)  # We standardize how we take in the voter_device_id
    sort_formula = request.GET.get('sort_formula', ALPHABETICAL_ASCENDING)  # Alternate: MOST_LINKED_ORGANIZATIONS
    ballot_location_shortcut = request.GET.get('ballot_location_shortcut', False)
    ballot_returned_we_vote_id = request.GET.get('ballot_returned_we_vote_id', False)
    google_civic_election_id = request.GET.get('google_civic_election_id', False)
    voter_issues_only = request.GET.get('voter_issues_only', False)
    include_voter_follow_status = request.GET.get('include_voter_follow_status', False)
    http_response = issues_retrieve_for_api(
        voter_device_id, sort_formula, google_civic_election_id,
        voter_issues_only, include_voter_follow_status,
        ballot_location_shortcut, ballot_returned_we_vote_id)
    return http_response


def issues_under_ballot_items_retrieve_view(request):  # issuesUnderBallotItemsRetrieve
    ballot_location_shortcut = request.GET.get('ballot_location_shortcut', False)
    ballot_returned_we_vote_id = request.GET.get('ballot_returned_we_vote_id', False)
    google_civic_election_id = request.GET.get('google_civic_election_id', False)
    http_response = issues_under_ballot_items_retrieve_for_api(
        google_civic_election_id, ballot_location_shortcut, ballot_returned_we_vote_id)
    return http_response


def retrieve_issues_to_follow_view(request):  # retrieveIssuesToFollow
    voter_device_id = get_voter_device_id(request)  # We standardize how we take in the voter_device_id
    sort_formula = request.GET.get('sort_formula', ALPHABETICAL_ASCENDING)  # Alternate: MOST_LINKED_ORGANIZATIONS
    http_response = retrieve_issues_to_follow_for_api(voter_device_id, sort_formula)
    return http_response


@login_required
def issues_import_from_master_server_view(request):
    # admin, analytics_admin, partner_organization, political_data_manager, political_data_viewer, verified_volunteer
    authority_required = {'admin'}
    if not voter_has_authority(request, authority_required):
        return redirect_to_sign_in_page(request, authority_required)

    if WE_VOTE_SERVER_ROOT_URL in ISSUES_SYNC_URL:
        messages.add_message(request, messages.ERROR, "Cannot sync with Master We Vote Server -- "
                                                      "this is the Master We Vote Server.")
        return HttpResponseRedirect(reverse('admin_tools:admin_home', args=()))

    google_civic_election_id = convert_to_int(request.GET.get('google_civic_election_id', 0))
    state_code = request.GET.get('state_code', '')

    results = issues_import_from_master_server(request)

    if not results['success']:
        messages.add_message(request, messages.ERROR, results['status'])
    else:
        messages.add_message(request, messages.INFO, 'Issues import completed. '
                                                     'Saved: {saved}, Updated: {updated}, '
                                                     'Not processed: {not_processed}'
                                                     ''.format(saved=results['issues_saved'],
                                                               updated=results['issues_updated'],
                                                               not_processed=results['issues_not_processed']))
    return HttpResponseRedirect(reverse('admin_tools:sync_dashboard', args=()) + "?google_civic_election_id=" +
                                str(google_civic_election_id) + "&state_code=" + str(state_code))


@login_required
def issue_list_view(request):
    # admin, analytics_admin, partner_organization, political_data_manager, political_data_viewer, verified_volunteer
    authority_required = \
        {'partner_organization', 'political_data_manager', 'political_data_viewer', 'verified_volunteer'}
    if not voter_has_authority(request, authority_required):
        return redirect_to_sign_in_page(request, authority_required)

    google_civic_election_id = convert_to_int(request.GET.get('google_civic_election_id', 0))
    state_code = request.GET.get('state_code', '')
    sta