import logging
import json
import stripe
from requests import ConnectionError
from urllib.parse import quote
from django import forms
from django.conf import settings
from django.core.mail import EmailMessage
from django.core.exceptions import ValidationError
from localflavor.us.us_states import USPS_CHOICES
from usps import USPSApi, Address
from captcha.fields import CaptchaField

from core.models import Order
from core import CoffeeGrind, ShippingContainer

logger = logging.getLogger(__name__)


class AddToCartForm(forms.Form):
    grind = forms.ChoiceField(choices=CoffeeGrind.GRIND_CHOICES)
    quantity = forms.IntegerField(min_value=1, max_value=20, initial=1)


class UpdateCartItemForm(forms.Form):
    quantity = forms.IntegerField(min_value=1, max_value=20, initial=1)
    update = forms.BooleanField(
        required=False,
        initial=True,
        widget=forms.HiddenInput
    )


class AddToSubscriptionForm(forms.Form):
    SEVEN_DAYS = 7
    FOURTEEN_DAYS = 14
    THIRTY_DAYS = 30
    SCHEDULE_CHOICES = [
        (SEVEN_DAYS, 'Every 7 days'),
        (FOURTEEN_DAYS, 'Every 14 days'),
        (THIRTY_DAYS, 'Every 30 days'),
    ]

    quantity = forms.IntegerField(min_value=1, initial=1)
    grind = forms.ChoiceField(choices=CoffeeGrind.GRIND_CHOICES)
    schedule = forms.ChoiceField(choices=SCHEDULE_CHOICES)


class AddressForm(forms.Form):
    full_name = forms.CharField()
    email = forms.EmailField()
    street_address_1 = forms.CharField()
    street_address_2 = forms.CharField(required=False)
    city = forms.CharField()
    state = forms.ChoiceField(
        choices=USPS_CHOICES
    )
    postal_code = forms.CharField()

    def process_full_name(self, full_name):
        name = full_name.split()

        if len(name) > 2:
            last_name = ''.join(name.pop(-1))
            first_name = ' '.join(name)
        elif len(name) > 1:
            first_name = name[0]
            last_name = name[1]
        else:
            first_name = name[0]
            last_name = ''

        return first_name, last_name

    def clean(self):
        cleaned_data = super().clean()
        address = Address(
            name=quote(cleaned_data.get('full_name')),
            address_1=quote(cleaned_data.get('street_address_1')),
            address_2=quote(cleaned_data.get('street_address_2')),
            city=quote(cleaned_data.get('city')),
            state=quote(cleaned_data.get('state')),
            zipcode=quote(cleaned_data.get('postal_code'))
        )
        usps = USPSApi(settings.USPS_USER_ID, test=True)

        try:
            validation = usps.validate_address(address)
        except ConnectionError:
            raise ValidationError(
                'Could not connect to USPS, try again.'
            )

        if 'Error' in validation.result['AddressValidateResponse']['Address']:
            error = validation.result['AddressValidateResponse']['Address']['Error']['Description']
            raise ValidationError(
                "USPS: " + error
            )

        try:
            cleaned_data['postal_code'] = validation.result['AddressValidateResponse']['Address']['Zip5']
        except KeyError:
            raise ValidationError(
                'Could not find Zip5'
            )


class CheckoutShippingForm(forms.Form):
    SHIPPING_CHOICES = [
        (ShippingContainer.MD_FLAT_RATE_BOX, 'Flate Rate Box - Medium'),
        (ShippingContainer.REGIONAL_RATE_BOX_B, 'Regional Rate Box B'),
    ]

    shipping_method = forms.ChoiceField(
        widget=forms.RadioSelect,
        choices=SHIPPING_CHOICES
    )


class OrderCreateForm(forms.ModelForm):
    email = forms.CharField(widget=forms.HiddenInput())
    first_name = forms.CharField(widget=forms.HiddenInput())
    last_name = forms.CharField(widget=forms.HiddenInput())

    class Meta:
        model = Order
        fields = (
            'total_net_amount',
            'shipping_total',
        )
        widgets = {
            'total_net_amount': forms.HiddenInput(),
            'shipping_total': forms.HiddenInput()
        }


class CouponApplyForm(forms.Form):
    code = forms.CharField(label='Coupon code')


class ContactForm(forms.Form):
    GOOGLE = 'Google Search'
    SHOP = 'The coffee shop'
    WOM = 'Word of mouth'
    PRODUCT = 'Coffee Bag'
    STORE = 'Store'
    OTHER = 'Other'

    REFERAL_CHOICES = [
        (GOOGLE, 'Google Search'),
        (SHOP, '"Better Living Through Coffee" coffee shop'),
        (WOM, 'Friend/Relative'),
        (PRODUCT, 'Our Coffee Bag'),
        (STORE, 'PT Food Coop/other store'),
        (OTHER, 'Other (please describe below)'),
    ]

    full_name = forms.CharField()
    email_address = forms.EmailField()
    referal = forms.ChoiceField(
        label='How did you find our website?',
        choices=REFERAL_CHOICES
    )
    subject = forms.CharField()
    message = forms.CharField(widget=forms.Textarea)
    captcha = CaptchaField()


class SubscriptionCreateForm(forms.Form):
    SEVEN_DAYS = 7
    FOURTEEN_DAYS = 14
    THIRTY_DAYS = 30
    SCHEDULE_CHOICES = [
        (SEVEN_DAYS, 'Every 7 days'),
        (FOURTEEN_DAYS, 'Every 14 days'),
        (THIRTY_DAYS, 'Every 30 days'),
    ]

    TWELVE_OZ = 12
    SIXTEEN_OZ = 16
    FIVE_LBS = 5
    SIZE_CHOICES = [
        (TWELVE_OZ, '12oz'),
        (SIXTEEN_OZ, '16oz'),
        (FIVE_LBS, '5lbs'),
    ]

    size = forms.ChoiceField(choices=SIZE_CHOICES)
    grind = forms.ChoiceField(choices=CoffeeGrind.GRIND_CHOICES)
    schedule = forms.ChoiceField(choices=SCHEDULE_CHOICES)
