import sform

from intranet.femida.src.candidates.models import Candidate
from intranet.femida.src.api.core.fetchers import query_params_data_getter
from intranet.femida.src.api.core.forms import (
    EMPTY_LABEL,
    CandidateSuggestField,
    UserSuggestField,
    BaseMetaForm,
    ConditionallyRequiredFieldsMixin,
    CandidateDuplicateChoiceField,
)
from intranet.femida.src.candidates.choices import (
    SUBMISSION_STATUSES,
    PUBLIC_SUBMISSION_SOURCES,
    REFERENCE_STATUSES,
    EXTERNAL_SUBMISSION_SOURCES,
    RECRUITER_SUBMISSION_STATUSES,
)
from intranet.femida.src.candidates.submissions.controllers import get_submission_duplicate_triples
from intranet.femida.src.communications.choices import MESSAGE_TEMPLATE_TYPES
from intranet.femida.src.communications.models import MessageTemplate
from intranet.femida.src.communications.validators import validate_future_time


class MergeCandidateForm(sform.SForm):

    candidate = CandidateSuggestField(state=sform.REQUIRED)


class SubmissionListFilterForm(sform.SForm):

    default_getter = query_params_data_getter

    recruiter = UserSuggestField()
    status = sform.ChoiceField(
        choices=SUBMISSION_STATUSES,
        empty_label=EMPTY_LABEL,
        default=SUBMISSION_STATUSES.new,
    )
    source = sform.ChoiceField(
        choices=PUBLIC_SUBMISSION_SOURCES,
        empty_label=EMPTY_LABEL,
    )
    reference__status = sform.ChoiceField(
        choices=REFERENCE_STATUSES,
        empty_label=EMPTY_LABEL,
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        user = self.context['user']
        self.fields['recruiter'].default = user.username
        if not user.is_reference_coordinator:
            self.fields.pop('reference__status', None)
            self.fields['status'].choices = RECRUITER_SUBMISSION_STATUSES


class SubmissionHandleForm(ConditionallyRequiredFieldsMixin, BaseMetaForm):

    # Фактический queryset положим в поле на этапе инициализации формы
    duplicate = CandidateDuplicateChoiceField(queryset=Candidate.unsafe.none())
    is_rejection = sform.BooleanField(default=False)
    text = sform.CharField()
    schedule_time = sform.DateTimeField(validators=[validate_future_time])

    CONDITIONALLY_REQUIRED = {
        'text': ('is_rejection', True),
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        duplicate = self.fields['duplicate']
        duplicate.queryset, duplicate.details = self._get_duplicates()
        submission = self.context['submission']
        if submission.source not in EXTERNAL_SUBMISSION_SOURCES:
            for field in ('is_rejection', 'text', 'schedule_time'):
                self.fields.pop(field)

    def _get_duplicates(self):
        submission = self.context['submission']
        duplicate_triples = get_submission_duplicate_triples(submission)

        candidate_ids = []
        details = {}
        for candidate, info, _ in duplicate_triples:
            candidate_ids.append(candidate.id)
            details[candidate.id] = info
        qs = Candidate.unsafe.filter(id__in=candidate_ids)
        return qs, details

    def meta_as_dict(self):
        return {
            'templates': dict(
                MessageTemplate.objects
                .filter(type=MESSAGE_TEMPLATE_TYPES.submission_rejection)
                .values_list('name', 'text')
            ),
            'publication_url': self.context['submission'].publication_url,
        }


class ReferenceActionForm(sform.SForm):

    comment = sform.CharField()
