{# Create workflow -#}

from collections.abc import Generator
from typing import Optional

from orchestrator.forms import FormPage
from orchestrator.forms.validators import Divider, Label, OrganisationId, MigrationSummary
from orchestrator.targets import Target
from orchestrator.types import FormGenerator, State, SubscriptionLifecycle, UUIDstr
from orchestrator.workflow import StepList, begin, step
from orchestrator.workflows.steps import store_process_subscription
from orchestrator.workflows.utils import create_workflow

from {{ product_types_module }}.{{ product.variable }} import {{ product.type }}Inactive, {{ product.type }}Provisioning
{%-if validation_imports %}
from workflows.{{ product.variable }}.shared.forms import {{ validation_imports | join(", ") }}
{%-endif %}

{% include 'additional_create_imports.j2' %}


def initial_input_form_generator(product_name: str) -> FormGenerator:
    # TODO add additional fields to form if needed

    class Create{{ product.type }}Form(FormPage):
        class Config:
            title = product_name

        organisation: OrganisationId
{% include "additional_create_input_fields.j2" ignore missing %}

        label_{{ product.variable }}_settings: Label
        divider_1: Divider

        {% for field in product_block.fields -%}
        {{ field.name }}: {% if field.required in ["provisioning", "active"] -%}Optional[{{ field.type }}]{% else -%}{{ field.type }}{% endif %}
        {% endfor -%}

{% for validation in validations %}
        """{{ validation.validation.description }}"""
        _validate_{{ validation.validation.id }}: classmethod = {{ validation.validation.id }}_validator()
{% endfor %}

    user_input = yield Create{{ product.type }}Form

    user_input_dict = user_input.dict()
    yield from create_summary_form(user_input_dict, product_name)

    return user_input_dict


def create_summary_form(
    user_input: dict,
    product_name: str,
) -> Generator:
    product_summary_fields = [{% for field in product_block.fields %} "{{ field.name }}",{% endfor -%}]

    class ProductSummary(MigrationSummary):
        data = {
            "labels": product_summary_fields,
            "columns": [[str(user_input[nm]) for nm in product_summary_fields]],
        }

    class SummaryForm(FormPage):
        class Config:
            title = f"{product_name} Summary"

        product_summary: ProductSummary
        divider_1: Divider

        # TODO fill in additional details if needed

    yield SummaryForm


@step("Construct Subscription model")
def construct_{{ product.variable }}_model(
    product: UUIDstr,
    organisation: UUIDstr,
    {% for field in product_block.fields -%}
    {{ field.name }}: {% if field.required in ["provisioning", "active"] %}Optional[{{ field.type }}]{% else %}{{ field.type }}{% endif %},
    {% endfor -%}
) -> State:
    {{ product.variable }} = {{ product.type }}Inactive.from_product_id(
        product_id=product,
        customer_id=organisation,
        status=SubscriptionLifecycle.INITIAL,
    )

    {%- for field in product_block.fields %}
    {{ product.variable }}.{{ product_block.name }}.{{ field.name }} = {{ field.name }}
    {%- endfor %}

    {{ product.variable }} = {{ product.type }}Provisioning.from_other_lifecycle({{ product.variable }}, SubscriptionLifecycle.PROVISIONING)
    {{ product.variable }}.description = subscription_description({{ product.variable }})

    return {
        "subscription": {{ product.variable }},
        "subscription_id": {{ product.variable }}.subscription_id,  # necessary to be able to use older generic step functions
        "subscription_description": {{ product.variable }}.description,
    }


{% include 'additional_create_steps.j2' %}


@create_workflow("Create {{ product.name }}", initial_input_form=initial_input_form_generator, additional_steps=additional_steps)
def create_{{ product.variable }}() -> StepList:
    return (
        begin
        >> construct_{{ product.variable }}_model
        >> store_process_subscription(Target.CREATE)
        # TODO add provision step(s)
    )
