"""
Chile specific form helpers.
"""

from django.forms import ValidationError
from django.forms.fields import RegexField, Select, EMPTY_VALUES
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_unicode


class CLRegionSelect(Select):
    """
    A Select widget that uses a list of Chilean Regions (Regiones)
    as its choices.
    """
    def __init__(self, attrs=None):
        from cl_regions import REGION_CHOICES
        super(CLRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)

class CLRutField(RegexField):
    """
    Chilean "Rol Unico Tributario" (RUT) field. This is the Chilean national
    identification number.

    Samples for testing are available from
    https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html
    """
    default_error_messages = {
        'invalid': _('Enter a valid Chilean RUT.'),
        'strict': _('Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.'),
        'checksum': _('The Chilean RUT is not valid.'),
    }

    def __init__(self, *args, **kwargs):
        if 'strict' in kwargs:
            del kwargs['strict']
            super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
                error_message=self.default_error_messages['strict'], *args, **kwargs)
        else:
            # In non-strict mode, accept RUTs that validate but do not exist in
            # the real world.
            super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', *args, **kwargs)

    def clean(self, value):
        """
        Check and clean the Chilean RUT.
        """
        super(CLRutField, self).clean(value)
        if value in EMPTY_VALUES:
            return u''
        rut, verificador = self._canonify(value)
        if self._algorithm(rut) == verificador:
            return self._format(rut, verificador)
        else:
            raise ValidationError(self.error_messages['checksum'])

    def _algorithm(self, rut):
        """
        Takes RUT in pure canonical form, calculates the verifier digit.
        """
        suma  = 0
        multi = 2
        for r in rut[::-1]:
            suma  += int(r) * multi
            multi += 1
            if multi == 8:
                multi = 2
        return u'0123456789K0'[11 - suma % 11]

    def _canonify(self, rut):
        """
        Turns the RUT into one normalized format. Returns a (rut, verifier)
        tuple.
        """
        rut = smart_unicode(rut).replace(' ', '').replace('.', '').replace('-', '')
        return rut[:-1], rut[-1]

    def _format(self, code, verifier=None):
        """
        Formats the RUT from canonical form to the common string representation.
        If verifier=None, then the last digit in 'code' is the verifier.
        """
        if verifier is None:
            verifier = code[-1]
            code = code[:-1]
        while len(code) > 3 and '.' not in code[:3]:
            pos = code.find('.')
            if pos == -1:
                new_dot = -3
            else:
                new_dot = pos - 3
            code = code[:new_dot] + '.' + code[new_dot:]
        return u'%s-%s' % (code, verifier)

