import attr
from typing import List, Optional


@attr.s(auto_attribs=True)
class VacancyAction(object):
    vacancy_id: int
    department: str or None = None
    fake_department: str or None = None
    action_id: str or None = None
    comment: str or None = None
    value_stream: str or None = None
    geography: str or None = None
    dep_chain: Optional[List[str]] = None
    force_recalculate_schemes: bool = False

    @staticmethod
    def _as_dict_filter_none(obj, recurse=True):
        return attr.asdict(obj, filter=lambda _, value: value is not None, recurse=recurse)

    @classmethod
    def from_dict(cls, vacancy_action):
        simple_fields = ('vacancy_id', 'action_id', 'comment', 'value_stream', 'geography')
        return cls(
            department=vacancy_action.get('department') or {},
            fake_department=vacancy_action.get('fake_department') or {},
            dep_chain=vacancy_action.get('__department_chain__'),
            **{f: vacancy_action.get(f) for f in simple_fields}
        )

    def copy_with_meta(self, **kwargs) -> 'VacancyAction':
        return VacancyAction(
            vacancy_id=self.vacancy_id,
            dep_chain=self.dep_chain,
            comment=self.comment,
            value_stream=self.value_stream,
            geography=self.geography,
            **kwargs
        )

    def as_dict(self):
        res = self._as_dict_filter_none(self, recurse=False)
        dep_chain = res.pop('dep_chain', None)

        if dep_chain is not None:
            res['__department_chain__'] = dep_chain

        res['department'] = self.department or ''
        res['fake_department'] = self.fake_department or ''

        return res
