import stripe
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import AbstractUser
from localflavor.us.us_states import USPS_CHOICES


class Address(models.Model):
    first_name = models.CharField(max_length=256, blank=True)
    last_name = models.CharField(max_length=256, blank=True)
    street_address_1 = models.CharField(max_length=256, blank=True)
    street_address_2 = models.CharField(max_length=256, blank=True)
    city = models.CharField(max_length=256, blank=True)
    state = models.CharField(
        max_length=2,
        choices=USPS_CHOICES,
        blank=True
    )
    postal_code = models.CharField(max_length=20, blank=True)

    def as_stripe_dict(self):
        return {
            'name': f'{self.first_name} {self.last_name}',
            'address': {
                'line1': self.street_address_1,
                'line2': self.street_address_2,
                'city': self.city,
                'state': self.state,
                'postal_code': self.postal_code
            }
        }

    def __str__(self):
        return f"""
            {self.first_name} {self.last_name}
            {self.street_address_1}
            {self.street_address_2}
            {self.city}, {self.state}, {self.postal_code}
        """

    def __iter__(self):
        yield ('address_line_1', self.street_address_1),
        yield ('address_line_2', self.street_address_2),
        yield ('admin_area_2', self.city),
        yield ('admin_area_1', self.state),
        yield ('postal_code', self.postal_code),
        yield ('country_code', 'US')

    class Meta:
        constraints = [
            models.UniqueConstraint(
                name='accounts_address_all_key',
                fields=[
                    'first_name',
                    'last_name',
                    'street_address_1',
                    'street_address_2',
                    'city',
                    'state',
                    'postal_code'
                ],
                violation_error_message='Duplicate: Address already exists.'
            )
        ]


class User(AbstractUser):
    addresses = models.ManyToManyField(
        Address, blank=True, related_name="user_addresses"
    )
    default_shipping_address = models.ForeignKey(
        Address, related_name="+", null=True, blank=True, on_delete=models.SET_NULL
    )
    default_billing_address = models.ForeignKey(
        Address, related_name="+", null=True, blank=True, on_delete=models.SET_NULL
    )
    stripe_id = models.CharField(max_length=255, blank=True)

    def get_or_create_stripe_id(self):
        if not self.stripe_id:
            response = stripe.Customer.create(
                name=self.first_name + ' ' + self.last_name,
                email=self.email
            )
            self.stripe_id = response['id']
            self.save()
        return self.stripe_id
