namespace Tiku.Infrastructure.Persistence;

internal static class PostgreSqlTenantConstraintSql
{
    public const string CreateTenantQuestionReferenceGuard = """
        create or replace function tiku_guard_tenant_question_reference()
        returns trigger
        language plpgsql
        as $$
        declare
            owner_mode text;
        begin
            select mode into owner_mode
            from tenants
            where id = new.question_owner_tenant_id;

            if owner_mode = 'platform_owned' then
                if new.source <> 'platform' then
                    raise exception 'tenant question reference to platform question must use platform source'
                        using errcode = '23514',
                              constraint = 'ck_tenant_question_references_platform_or_self_owner';
                end if;

                return new;
            end if;

            if new.question_owner_tenant_id = new.tenant_id then
                if new.source <> 'tenant' then
                    raise exception 'tenant question reference to tenant-owned question must use tenant source'
                        using errcode = '23514',
                              constraint = 'ck_tenant_question_references_platform_or_self_owner';
                end if;

                return new;
            end if;

            raise exception 'tenant question reference cannot point to another tenant private question'
                using errcode = '23514',
                      constraint = 'ck_tenant_question_references_platform_or_self_owner';
        end;
        $$;

        create trigger trg_tenant_question_references_platform_or_self_owner
        before insert or update of tenant_id, question_owner_tenant_id, question_id, source
        on tenant_question_references
        for each row
        execute function tiku_guard_tenant_question_reference();
        """;

    public const string CreateTaxonomyParentGuard = """
        create or replace function tiku_guard_taxonomy_parent_owner()
        returns trigger
        language plpgsql
        as $$
        declare
            parent_owner_mode text;
        begin
            if new.parent_owner_tenant_id is null and new.parent_id is null then
                return new;
            end if;

            select mode into parent_owner_mode
            from tenants
            where id = new.parent_owner_tenant_id;

            if parent_owner_mode = 'platform_owned' or new.parent_owner_tenant_id = new.tenant_id then
                return new;
            end if;

            raise exception 'taxonomy parent must belong to platform or current tenant'
                using errcode = '23514',
                      constraint = 'ck_taxonomy_nodes_parent_platform_or_self_owner';
        end;
        $$;

        create trigger trg_taxonomy_nodes_parent_platform_or_self_owner
        before insert or update of tenant_id, parent_owner_tenant_id, parent_id
        on taxonomy_nodes
        for each row
        execute function tiku_guard_taxonomy_parent_owner();
        """;

    public const string DropTenantGuards = """
        drop trigger if exists trg_tenant_question_references_platform_or_self_owner on tenant_question_references;
        drop function if exists tiku_guard_tenant_question_reference();
        drop trigger if exists trg_taxonomy_nodes_parent_platform_or_self_owner on taxonomy_nodes;
        drop function if exists tiku_guard_taxonomy_parent_owner();
        """;
}
