class NonCompaniesHouseEnrolmentView(
    core.mixins.CreateUserProfileMixin, CreateCompanyProfileMixin,
    UserJourneySuccessRoutingMixin, BaseEnrolmentWizardView
):
    steps_list_conf = helpers.StepsListConf(
        form_labels_user=[
            PROGRESS_STEP_LABEL_BUSINESS_TYPE,
            PROGRESS_STEP_LABEL_BUSINESS_DETAILS,
            PROGRESS_STEP_LABEL_PERSONAL_INFO,
        ],
        form_labels_anon=[
            PROGRESS_STEP_LABEL_BUSINESS_TYPE,
            PROGRESS_STEP_LABEL_USER_ACCOUNT,
            PROGRESS_STEP_LABEL_VERIFICATION,
            PROGRESS_STEP_LABEL_BUSINESS_DETAILS,
            PROGRESS_STEP_LABEL_PERSONAL_INFO,
        ],
    )
    progress_conf = helpers.ProgressIndicatorConf(
        step_counter_user={
            COMPANY_SEARCH: 2,
            PERSONAL_INFO: 3,
        },
        step_counter_anon={
            USER_ACCOUNT: 2,
            VERIFICATION: 3,
            COMPANY_SEARCH: 4,
            PERSONAL_INFO: 5,
        },
    )

    form_list = (
        (USER_ACCOUNT, forms.UserAccount),
        (VERIFICATION, forms.UserAccountVerification),
        (COMPANY_SEARCH, forms.NonCompaniesHouseSearch),
        (PERSONAL_INFO, core.forms.PersonalDetails),
    )

    templates = {
        USER_ACCOUNT: 'enrolment/user-account.html',
        VERIFICATION: 'enrolment/user-account-verification.html',
        COMPANY_SEARCH: 'enrolment/non-companies-house-business-details.html',
        PERSONAL_INFO: 'enrolment/non-companies-house-personal-details.html',
        FINISHED: 'enrolment/non-companies-house-success.html',
    }

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if self.steps.current == PERSONAL_INFO:
            context['company'] = self.get_cleaned_data_for_step(COMPANY_SEARCH)
        return context

    def done(self, form_list, form_dict, **kwargs):
        self.create_user_profile(form_dict[PERSONAL_INFO])
        data = self.serialize_form_list(form_list)
        self.create_company_profile(data)
        return super().done(form_list=form_list, form_dict=form_dict, **kwargs)
class IndividualUserEnrolmentView(
    core.mixins.CreateUserProfileMixin, BaseEnrolmentWizardView
):
    steps_list_conf = helpers.StepsListConf(
        form_labels_user=[
            PROGRESS_STEP_LABEL_BUSINESS_TYPE,
            PROGRESS_STEP_LABEL_PERSONAL_INFO
        ],
        form_labels_anon=[
            PROGRESS_STEP_LABEL_BUSINESS_TYPE,
            PROGRESS_STEP_LABEL_INDIVIDUAL_USER_ACCOUNT,
            PROGRESS_STEP_LABEL_VERIFICATION,
            PROGRESS_STEP_LABEL_PERSONAL_INFO
        ],
    )

    progress_conf = helpers.ProgressIndicatorConf(
        step_counter_user={
            PERSONAL_INFO: 3
        },
        step_counter_anon={
            USER_ACCOUNT: 2,
            VERIFICATION: 3,
            PERSONAL_INFO: 4
        },
    )

    form_list = (
        (USER_ACCOUNT, forms.UserAccount),
        (VERIFICATION, forms.UserAccountVerification),
        (PERSONAL_INFO, forms.IndividualPersonalDetails),
    )

    templates = {
        USER_ACCOUNT: 'enrolment/individual-user-account.html',
        VERIFICATION: 'enrolment/user-account-verification.html',
        PERSONAL_INFO: 'enrolment/individual-personal-details.html',
        FINISHED: 'enrolment/individual-success.html',
    }

    def done(self, form_list, form_dict, **kwargs):
        self.create_user_profile(form_dict[PERSONAL_INFO])
        return TemplateResponse(
            self.request,
            self.templates[FINISHED]
        )
class ResendVerificationCodeView(
    RedirectLoggedInMixin,
    RestartOnStepSkipped,
    ProgressIndicatorMixin,
    StepsListMixin,
    UserAccountEnrolmentHandlerMixin,
    NamedUrlSessionWizardView
):

    form_list = (
        (RESEND_VERIFICATION, forms.ResendVerificationCode),
        (VERIFICATION, forms.UserAccountVerification),
    )

    templates = {
        RESEND_VERIFICATION: 'enrolment/user-account-resend-verification.html',
        VERIFICATION: 'enrolment/user-account-verification.html',
        FINISHED: 'enrolment/start.html',
    }

    progress_conf = helpers.ProgressIndicatorConf(
        step_counter_anon={RESEND_VERIFICATION: 1, VERIFICATION: 2},
        # logged in users should not get here
        step_counter_user={},
    )
    steps_list_conf = helpers.StepsListConf(
        form_labels_anon=[
            'Resend verification',
            PROGRESS_STEP_LABEL_VERIFICATION,
        ],
        # logged in users should not get here
        form_labels_user=[],
    )

    def get_template_names(self):
        return [self.templates[self.steps.current]]

    def render_done(self, form, **kwargs):
        choice = self.request.session.get(SESSION_KEY_COMPANY_CHOICE)
        if choice == constants.COMPANIES_HOUSE_COMPANY:
            url = URL_COMPANIES_HOUSE_ENROLMENT
        elif choice == constants.NON_COMPANIES_HOUSE_COMPANY:
            url = URL_NON_COMPANIES_HOUSE_ENROLMENT
        elif choice == constants.NOT_COMPANY:
            url = URL_INDIVIDUAL_ENROLMENT
        else:
            url = reverse('enrolment-business-type')
        response = self.validate_code(
            form=form,
            response=redirect(url)
        )
        return response

    def render_next_step(self, form, **kwargs):
        response = super().render_next_step(form, **kwargs)
        if form.prefix == RESEND_VERIFICATION:
            email = form.cleaned_data['email']
            verification_code = helpers.regenerate_verification_code(email)
            if verification_code:
                helpers.send_verification_code_email(
                    email=email,
                    verification_code=verification_code,
                    form_url=self.request.path,
                )
        return response

    def get_context_data(self, *args, **kwargs):
        return super().get_context_data(
            verification_missing_url=urls.build_great_url(
                'contact/triage/great-account/verification-missing/'
            ),
            contact_url=urls.build_great_url('contact/domestic/'),
            *args,
            **kwargs
        )

    def get_form_initial(self, step):
        form_initial = super().get_form_initial(step)
        if step == VERIFICATION:
            data = self.get_cleaned_data_for_step(RESEND_VERIFICATION)
            if data:
                form_initial['email'] = data['email']
        return form_initial
class PreVerifiedEnrolmentView(BaseEnrolmentWizardView):
    steps_list_conf = helpers.StepsListConf(
        form_labels_user=[PROGRESS_STEP_LABEL_PERSONAL_INFO],
        form_labels_anon=[
            PROGRESS_STEP_LABEL_USER_ACCOUNT,
            PROGRESS_STEP_LABEL_VERIFICATION,
            PROGRESS_STEP_LABEL_PERSONAL_INFO,
        ],
    )
    progress_conf = helpers.ProgressIndicatorConf(
        step_counter_user={PERSONAL_INFO: 1},
        step_counter_anon={
            USER_ACCOUNT: 1,
            VERIFICATION: 2,
            PERSONAL_INFO: 3,
        },
    )

    form_list = (
        (USER_ACCOUNT, forms.UserAccount),
        (VERIFICATION, forms.UserAccountVerification),
        (PERSONAL_INFO, core.forms.PersonalDetails),
    )

    templates = {
        USER_ACCOUNT: 'enrolment/user-account.html',
        VERIFICATION: 'enrolment/user-account-verification.html',
        PERSONAL_INFO: 'enrolment/preverified-personal-details.html',
        FAILURE: 'enrolment/failure-pre-verified.html',
    }

    def get(self, *args, **kwargs):
        key = self.request.GET.get('key')
        if key:
            data = helpers.retrieve_preverified_company(key)
            if data:
                self.request.session[SESSION_KEY_COMPANY_DATA] = data
                self.request.session[SESSION_KEY_ENROL_KEY] = key
                self.request.session.save()
            else:
                return redirect(reverse('enrolment-start'))
        if self.steps.current == PERSONAL_INFO:
            if not self.request.session.get(SESSION_KEY_COMPANY_DATA):
                return redirect(reverse('enrolment-start'))
        return super().get(*args, **kwargs)

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        if self.steps.current == PERSONAL_INFO:
            context['company'] = (
                self.request.session[SESSION_KEY_COMPANY_DATA]
            )
        return context

    def done(self, form_list, **kwargs):
        try:
            self.claim_company(self.serialize_form_list(form_list))
        except HTTPError:
            return TemplateResponse(self.request, self.templates[FAILURE])
        else:
            messages.success(self.request, 'Business profile created')
            return redirect('find-a-buyer')

    def claim_company(self, data):
        helpers.claim_company(
            enrolment_key=self.request.session[SESSION_KEY_ENROL_KEY],
            personal_name=f'{data["given_name"]} {data["family_name"]}',
            sso_session_id=self.request.user.session_id,
        )

    def serialize_form_list(self, form_list):
        data = {}
        for form in form_list:
            data.update(form.cleaned_data)
        return data
class CompaniesHouseEnrolmentView(
    core.mixins.CreateUserProfileMixin,
    CreateCompanyProfileMixin,
    UserJourneySuccessRoutingMixin,
    BaseEnrolmentWizardView,
):
    progress_conf = helpers.ProgressIndicatorConf(
        step_counter_user={
            COMPANY_SEARCH: 2,
            BUSINESS_INFO: 2,
            PERSONAL_INFO: 3,
        },
        step_counter_anon={
            USER_ACCOUNT: 2,
            VERIFICATION: 3,
            COMPANY_SEARCH: 4,
            BUSINESS_INFO: 4,
            PERSONAL_INFO: 5,
        },
    )
    steps_list_conf = helpers.StepsListConf(
        form_labels_user=[
            PROGRESS_STEP_LABEL_BUSINESS_TYPE,
            PROGRESS_STEP_LABEL_BUSINESS_DETAILS,
            PROGRESS_STEP_LABEL_PERSONAL_INFO,
        ],
        form_labels_anon=[
            PROGRESS_STEP_LABEL_BUSINESS_TYPE,
            PROGRESS_STEP_LABEL_USER_ACCOUNT,
            PROGRESS_STEP_LABEL_VERIFICATION,
            PROGRESS_STEP_LABEL_BUSINESS_DETAILS,
            PROGRESS_STEP_LABEL_PERSONAL_INFO,
        ],
    )

    form_list = (
        (USER_ACCOUNT, forms.UserAccount),
        (VERIFICATION, forms.UserAccountVerification),
        (COMPANY_SEARCH, forms.CompaniesHouseSearch),
        (BUSINESS_INFO, forms.CompaniesHouseBusinessDetails),
        (PERSONAL_INFO, core.forms.PersonalDetails),
    )

    templates = {
        USER_ACCOUNT: 'enrolment/user-account.html',
        VERIFICATION: 'enrolment/user-account-verification.html',
        COMPANY_SEARCH: 'enrolment/companies-house-search.html',
        BUSINESS_INFO: 'enrolment/companies-house-business-details.html',
        PERSONAL_INFO: 'enrolment/companies-house-personal-details.html',
        FINISHED: 'enrolment/companies-house-success.html',
    }

    def get_form_kwargs(self, step=None):
        form_kwargs = super().get_form_kwargs(step=step)
        if step == BUSINESS_INFO:
            previous_data = self.get_cleaned_data_for_step(COMPANY_SEARCH)
            if previous_data:
                form_kwargs['company_data'] = helpers.get_company_profile(
                    number=previous_data['company_number'],
                    session=self.request.session,
                )
                form_kwargs['is_enrolled'] = helpers.get_is_enrolled(
                    company_number=previous_data['company_number'],
                    session=self.request.session,
                )
        elif step == COMPANY_SEARCH:
            form_kwargs['session'] = self.request.session
        return form_kwargs

    def serialize_form_list(self, form_list):
        return {
            **super().serialize_form_list(form_list),
            'company_type': 'COMPANIES_HOUSE',
        }

    def done(self, form_list, form_dict, **kwargs):
        self.create_user_profile(form_dict[PERSONAL_INFO])
        data = self.serialize_form_list(form_list)
        is_enrolled = helpers.get_is_enrolled(
            company_number=data['company_number'],
            session=self.request.session,
        )
        if is_enrolled:
            helpers.request_collaboration(
                company_number=data['company_number'],
                email=self.request.user.email,
                name=f"{data['given_name']} {data['family_name']}",
                form_url=self.request.path,
            )
        else:
            self.create_company_profile(data)
        return super().done(form_list=form_list, form_dict=form_dict, **kwargs)