from ..utils import _make_pseudo_id
from .base import BaseModel, SourceMixin, AssociatedLinkMixin, LinkMixin
from .schemas.event import schema
from pupa.exceptions import ScrapeValueError


class EventAgendaItem(dict, AssociatedLinkMixin):
    event = None

    def __init__(self, description, event):
        super(EventAgendaItem, self).__init__({
            "description": description,
            "classification": [],
            "related_entities": [],
            "subjects": [],
            "media": [],
            "notes": [],
            "order": str(len(event.agenda)),
            "extras": {},
        })
        self.event = event

    def add_subject(self, what):
        self['subjects'].append(what)

    def add_classification(self, what):
        self['classification'].append(what)

    def add_vote_event(self, vote_event, *, id=None, note='consideration'):
        self.add_entity(name=vote_event, entity_type='vote_event', id=id, note=note)

    def add_committee(self, committee, *, id=None, note='participant'):
        self.add_entity(name=committee, entity_type='organization', id=id, note=note)

    def add_bill(self, bill, *, id=None, note='consideration'):
        self.add_entity(name=bill, entity_type='bill', id=id, note=note)

    def add_person(self, person, *, id=None, note='participant'):
        self.add_entity(name=person, entity_type='person', id=id, note=note)

    def add_media_link(self, note, url, media_type, *, text='', type='media',
                       on_duplicate='error'):
        return self._add_associated_link(collection='media', note=note, url=url, text=text,
                                         media_type=media_type, on_duplicate=on_duplicate)

    def add_entity(self, name, entity_type, *, id, note):
        ret = {
            "name": name,
            "entity_type": entity_type,
            "note": note
        }
        if id:
            ret['id'] = id
        elif entity_type:
            if entity_type in ('organization', 'person'):
                id = _make_pseudo_id(name=name)
            elif entity_type in ('bill', 'vote_event'):
                id = _make_pseudo_id(identifier=name)
            else:
                raise ScrapeValueError('attempt to call add_entity with unsupported '
                                       'entity type: {}'.format(entity_type))
            ret[entity_type + '_id'] = id

        self['related_entities'].append(ret)


class Event(BaseModel, SourceMixin, AssociatedLinkMixin, LinkMixin):
    """
    Details for an event in .format
    """
    _type = 'event'
    _schema = schema

    def __init__(self, name, start_date, *,
                 location_name=None,
                 all_day=False, description="", end_date="",
                 status="confirmed", classification="event"
                 ):
        super(Event, self).__init__()
        self.start_date = start_date
        self.all_day = all_day
        self.end_date = end_date
        self.name = name
        self.description = description
        self.status = status
        self.classification = classification
        if location_name:
            self.location = {"name": location_name, "note": "", "coordinates": None}
        else:
            self.location = None
        self.documents = []
        self.participants = []
        self.media = []
        self.agenda = []

    def __str__(self):
        return '{} {}'.format(self.start_date, self.name.strip())

    def set_location(self, name, *, note="", url="", coordinates=None):
        self.location = {"name": name, "note": note, "url": url, "coordinates": coordinates}

    def add_participant(self, name, type, *, id=None, note='participant'):
        p = {
            "name": name,
            "entity_type": type,
            "note": note
        }
        if id:
            p['id'] = id
        elif type:
            id = _make_pseudo_id(name=name)
            p[type + '_id'] = id

        self.participants.append(p)

    def add_person(self, name, *, id=None, note='participant'):
        return self.add_participant(name=name, type='person', id=id, note=note)

    def add_committee(self, name, *, id=None, note='participant'):
        return self.add_participant(name=name, type='organization', id=id, note=note)

    def add_agenda_item(self, description):
        obj = EventAgendaItem(description, self)
        self.agenda.append(obj)
        return obj

    def add_media_link(self, note, url, media_type, *, text='',
                       type='media', on_duplicate='error', date=''):
        return self._add_associated_link(collection='media',
                                         note=note,
                                         url=url,
                                         text=text,
                                         media_type=media_type,
                                         on_duplicate=on_duplicate,
                                         date=date)

    def add_document(self, note, url, *, text='', media_type='', on_duplicate='error', date=''):
        return self._add_associated_link(collection='documents',
                                         note=note, url=url,
                                         text=text,
                                         media_type=media_type,
                                         on_duplicate=on_duplicate,
                                         date=date)
