"""
This module contains temporary functions that are used to support the scaffolding of the core platform functionality.

We anticipate that they should not be used by any of the real domains themselves (eg apply, assess, monitor), but are
required to support the technical build-out of the platform.

This file should be removed once the scaffolding is complete and some domain skins are in place.

The only place that should import from here is the `app.developers` package.
"""

from uuid import UUID

from sqlalchemy import delete, select, update

from app.common.data.models import (
    Collection,
    ComponentReference,
    Grant,
    Submission,
)
from app.common.data.models_user import User
from app.common.data.types import DataSourceType
from app.extensions import db


def delete_grant(grant_id: UUID) -> None:
    # Not optimised; do not lift+shift unedited.
    db.session.execute(
        update(Collection)
        .where(Collection.grant_id == grant_id, Collection.submission_name_question_id.is_not(None))
        .values(submission_name_question_id=None)
    )
    grant = db.session.query(Grant).where(Grant.id == grant_id).one()

    custom_data_sources_to_delete = [
        c.data_source
        for collection in grant.collections
        for form in collection.forms
        for c in form._all_components
        if hasattr(c, "data_source") and c.data_source and c.data_source.type == DataSourceType.CUSTOM
    ]
    non_custom_data_sources_to_delete = [
        ds for collection in grant.collections for ds in collection.data_sources if ds.type != DataSourceType.CUSTOM
    ]

    if non_custom_data_sources_to_delete:
        non_custom_ds_ids = [ds.id for ds in non_custom_data_sources_to_delete]
        db.session.execute(
            delete(ComponentReference).where(ComponentReference.depends_on_data_source_id.in_(non_custom_ds_ids))
        )
        for ds in non_custom_data_sources_to_delete:
            db.session.delete(ds)
        db.session.flush()

    db.session.delete(grant)

    for ds in custom_data_sources_to_delete:
        db.session.delete(ds)

    db.session.flush()


def get_submission_by_collection_and_user(collection: Collection, user: User) -> Submission | None:
    return db.session.scalar(
        select(Submission).where(Submission.collection == collection, Submission.created_by == user)
    )
