from django.core.validators import ValidationError


class StaffFormGrid(object):
    grid_level_error_key = 'errors'

    def __init__(self, form_class, initial=None, data=None):
        self.form_class = form_class
        self._errors = None
        if initial:
            self.forms = [self.form_class(initial=_data) for _data in initial]
        elif data:
            self.forms = [self.form_class(data=_data) for _data in data]
        else:
            self.forms = []

    def is_valid(self):
        return not self.errors()

    def errors(self):
        if self._errors is not None:
            return self._errors
        self._errors = {}

        for i, form in enumerate(self.forms):
            if not form.is_valid():
                self._errors[i] = form.errors

        for attr_name in dir(self):
            if attr_name.startswith('validate_'):
                try:
                    getattr(self, attr_name)()
                except ValidationError as e:
                    self._errors.setdefault(
                        self.grid_level_error_key, []
                    ).append({'error_key': str(e)})

        return self._errors

    def collect_field_value(self, field_name):
        return set([form.cleaned_data.get(field_name) for form in self.forms])

    def choices_as_front_dict(self):
        return self.form_class().choices_as_front_dict()

    def as_front_dict(self):
        return [form.as_front_dict() for form in self.forms]

    def append(self, data):
        form = self.form_class(data=data)
        self.forms.append(form)
        return form

    @property
    def cleaned_data(self):
        return [form.cleaned_data for form in self.forms]
