import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'

/**
 * Migration: Blogging Collections & Blocks
 *
 * Erstellt:
 * - Tags Collection
 * - Authors Collection
 * - Posts-Erweiterungen (Tags, Author Relations, Reading Time)
 * - AuthorBioBlock, RelatedPostsBlock, ShareButtonsBlock, TableOfContentsBlock
 */

export async function up({ db }: MigrateUpArgs): Promise<void> {
  // ========================================
  // Tags Collection
  // ========================================
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "tags" (
      "id" serial PRIMARY KEY NOT NULL,
      "slug" varchar NOT NULL UNIQUE,
      "color" varchar,
      "updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
      "created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
    );

    CREATE TABLE IF NOT EXISTS "tags_locales" (
      "name" varchar NOT NULL,
      "description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" integer NOT NULL
    );

    ALTER TABLE "tags_locales"
      ADD CONSTRAINT "tags_locales_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."tags"("id") ON DELETE cascade ON UPDATE no action;

    CREATE UNIQUE INDEX IF NOT EXISTS "tags_locales_locale_parent_id_unique"
      ON "tags_locales" USING btree ("_locale", "_parent_id");

    CREATE INDEX IF NOT EXISTS "tags_created_at_idx"
      ON "tags" USING btree ("created_at");
  `)

  // Tags Tenant Column (für Multi-Tenant Plugin)
  await db.execute(sql`
    ALTER TABLE "tags" ADD COLUMN IF NOT EXISTS "tenant_id" integer;

    ALTER TABLE "tags"
      ADD CONSTRAINT "tags_tenant_id_fk"
      FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "tags_tenant_idx"
      ON "tags" USING btree ("tenant_id");
  `)

  // ========================================
  // Authors Collection
  // ========================================
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "authors" (
      "id" serial PRIMARY KEY NOT NULL,
      "name" varchar NOT NULL,
      "slug" varchar NOT NULL UNIQUE,
      "avatar_id" integer,
      "email" varchar,
      "website" varchar,
      "social_twitter" varchar,
      "social_linkedin" varchar,
      "social_github" varchar,
      "social_instagram" varchar,
      "linked_team_id" integer,
      "linked_user_id" integer,
      "is_active" boolean DEFAULT true,
      "is_guest" boolean DEFAULT false,
      "featured" boolean DEFAULT false,
      "updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
      "created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
    );

    CREATE TABLE IF NOT EXISTS "authors_locales" (
      "bio" jsonb,
      "bio_short" varchar,
      "title" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" integer NOT NULL
    );

    ALTER TABLE "authors"
      ADD CONSTRAINT "authors_avatar_id_fk"
      FOREIGN KEY ("avatar_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;

    ALTER TABLE "authors"
      ADD CONSTRAINT "authors_linked_team_id_fk"
      FOREIGN KEY ("linked_team_id") REFERENCES "public"."team"("id") ON DELETE set null ON UPDATE no action;

    ALTER TABLE "authors"
      ADD CONSTRAINT "authors_linked_user_id_fk"
      FOREIGN KEY ("linked_user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;

    ALTER TABLE "authors_locales"
      ADD CONSTRAINT "authors_locales_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."authors"("id") ON DELETE cascade ON UPDATE no action;

    CREATE UNIQUE INDEX IF NOT EXISTS "authors_locales_locale_parent_id_unique"
      ON "authors_locales" USING btree ("_locale", "_parent_id");

    CREATE INDEX IF NOT EXISTS "authors_avatar_idx"
      ON "authors" USING btree ("avatar_id");

    CREATE INDEX IF NOT EXISTS "authors_created_at_idx"
      ON "authors" USING btree ("created_at");
  `)

  // Authors Tenant Column
  await db.execute(sql`
    ALTER TABLE "authors" ADD COLUMN IF NOT EXISTS "tenant_id" integer;

    ALTER TABLE "authors"
      ADD CONSTRAINT "authors_tenant_id_fk"
      FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "authors_tenant_idx"
      ON "authors" USING btree ("tenant_id");
  `)

  // ========================================
  // Posts-Erweiterungen
  // ========================================

  // Tags Relationship (posts_rels für tags)
  await db.execute(sql`
    -- Add tags path to posts_rels if needed
    DO $$
    BEGIN
      IF NOT EXISTS (
        SELECT 1 FROM posts_rels WHERE path = 'tags' LIMIT 1
      ) THEN
        -- tags_id column might not exist yet
        ALTER TABLE "posts_rels" ADD COLUMN IF NOT EXISTS "tags_id" integer;

        ALTER TABLE "posts_rels"
          ADD CONSTRAINT "posts_rels_tags_fk"
          FOREIGN KEY ("tags_id") REFERENCES "public"."tags"("id") ON DELETE cascade ON UPDATE no action;

        CREATE INDEX IF NOT EXISTS "posts_rels_tags_id_idx"
          ON "posts_rels" USING btree ("tags_id");
      END IF;
    END
    $$;
  `)

  // Author Relationship (author_id and co_authors via posts_rels)
  await db.execute(sql`
    ALTER TABLE "posts" ADD COLUMN IF NOT EXISTS "author_id" integer;
    ALTER TABLE "posts" ADD COLUMN IF NOT EXISTS "author_legacy" varchar;
    ALTER TABLE "posts" ADD COLUMN IF NOT EXISTS "reading_time" integer;

    ALTER TABLE "posts"
      ADD CONSTRAINT "posts_author_id_fk"
      FOREIGN KEY ("author_id") REFERENCES "public"."authors"("id") ON DELETE set null ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "posts_author_idx"
      ON "posts" USING btree ("author_id");

    -- Co-Authors via posts_rels
    ALTER TABLE "posts_rels" ADD COLUMN IF NOT EXISTS "authors_id" integer;

    ALTER TABLE "posts_rels"
      ADD CONSTRAINT "posts_rels_authors_fk"
      FOREIGN KEY ("authors_id") REFERENCES "public"."authors"("id") ON DELETE cascade ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "posts_rels_authors_id_idx"
      ON "posts_rels" USING btree ("authors_id");
  `)

  // ========================================
  // AuthorBioBlock
  // ========================================
  await db.execute(sql`
    -- Enums for AuthorBioBlock
    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_author_bio_source" AS ENUM('post', 'manual');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_author_bio_layout" AS ENUM('card', 'inline', 'compact', 'feature');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_author_bio_show_bio" AS ENUM('none', 'short', 'full');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_author_bio_avatar_size" AS ENUM('sm', 'md', 'lg');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_author_bio_avatar_shape" AS ENUM('circle', 'square', 'rounded');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_author_bio_bg" AS ENUM('none', 'light', 'dark', 'accent');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "pages_blocks_author_bio_block" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL,
      "_path" text NOT NULL,
      "id" varchar PRIMARY KEY NOT NULL,
      "source" "enum_pages_blocks_author_bio_source" DEFAULT 'post',
      "show_co_authors" boolean DEFAULT true,
      "layout" "enum_pages_blocks_author_bio_layout" DEFAULT 'card',
      "show_avatar" boolean DEFAULT true,
      "show_name" boolean DEFAULT true,
      "show_title" boolean DEFAULT true,
      "show_bio" "enum_pages_blocks_author_bio_show_bio" DEFAULT 'short',
      "show_social" boolean DEFAULT true,
      "show_email" boolean DEFAULT false,
      "show_website" boolean DEFAULT false,
      "show_post_count" boolean DEFAULT false,
      "style_avatar_size" "enum_pages_blocks_author_bio_avatar_size" DEFAULT 'md',
      "style_avatar_shape" "enum_pages_blocks_author_bio_avatar_shape" DEFAULT 'circle',
      "style_bg" "enum_pages_blocks_author_bio_bg" DEFAULT 'light',
      "style_border" boolean DEFAULT false,
      "style_shadow" boolean DEFAULT false,
      "style_divider" boolean DEFAULT true,
      "link_to_profile" boolean DEFAULT true,
      "block_name" varchar
    );

    CREATE TABLE IF NOT EXISTS "pages_blocks_author_bio_block_locales" (
      "label" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL
    );

    -- Authors relationship for manual selection
    CREATE TABLE IF NOT EXISTS "pages_blocks_author_bio_block_rels" (
      "id" serial PRIMARY KEY NOT NULL,
      "order" integer,
      "parent_id" varchar NOT NULL,
      "path" varchar NOT NULL,
      "authors_id" integer
    );

    ALTER TABLE "pages_blocks_author_bio_block"
      ADD CONSTRAINT "pages_blocks_author_bio_block_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_author_bio_block_locales"
      ADD CONSTRAINT "pages_blocks_author_bio_block_locales_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_author_bio_block"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_author_bio_block_rels"
      ADD CONSTRAINT "pages_blocks_author_bio_block_rels_parent_fk"
      FOREIGN KEY ("parent_id") REFERENCES "public"."pages_blocks_author_bio_block"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_author_bio_block_rels"
      ADD CONSTRAINT "pages_blocks_author_bio_block_rels_authors_fk"
      FOREIGN KEY ("authors_id") REFERENCES "public"."authors"("id") ON DELETE cascade ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "pages_blocks_author_bio_block_order_idx"
      ON "pages_blocks_author_bio_block" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "pages_blocks_author_bio_block_parent_id_idx"
      ON "pages_blocks_author_bio_block" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "pages_blocks_author_bio_block_path_idx"
      ON "pages_blocks_author_bio_block" USING btree ("_path");

    CREATE UNIQUE INDEX IF NOT EXISTS "pages_blocks_author_bio_block_locales_locale_parent_id_unique"
      ON "pages_blocks_author_bio_block_locales" USING btree ("_locale", "_parent_id");
  `)

  // ========================================
  // RelatedPostsBlock
  // ========================================
  await db.execute(sql`
    -- Enums for RelatedPostsBlock
    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_source" AS ENUM('auto', 'manual', 'category', 'tag', 'latest', 'popular', 'author');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_layout" AS ENUM('grid', 'list', 'slider', 'compact', 'cards');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_cols" AS ENUM('2', '3', '4');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_img_ratio" AS ENUM('square', '4-3', '16-9', '3-4');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_rounded" AS ENUM('none', 'sm', 'md', 'lg');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_hover" AS ENUM('none', 'lift', 'zoom', 'overlay');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_bg" AS ENUM('none', 'light', 'dark');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_related_posts_gap" AS ENUM('16', '24', '32');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "pages_blocks_related_posts_block" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL,
      "_path" text NOT NULL,
      "id" varchar PRIMARY KEY NOT NULL,
      "source" "enum_pages_blocks_related_posts_source" DEFAULT 'auto',
      "category_id" integer,
      "tag_id" integer,
      "limit" integer DEFAULT 3,
      "exclude_current" boolean DEFAULT true,
      "layout" "enum_pages_blocks_related_posts_layout" DEFAULT 'grid',
      "cols" "enum_pages_blocks_related_posts_cols" DEFAULT '3',
      "show_image" boolean DEFAULT true,
      "show_date" boolean DEFAULT true,
      "show_author" boolean DEFAULT false,
      "show_category" boolean DEFAULT true,
      "show_excerpt" boolean DEFAULT true,
      "show_reading_time" boolean DEFAULT false,
      "show_tags" boolean DEFAULT false,
      "style_img_ratio" "enum_pages_blocks_related_posts_img_ratio" DEFAULT '16-9',
      "style_rounded" "enum_pages_blocks_related_posts_rounded" DEFAULT 'md',
      "style_shadow" boolean DEFAULT false,
      "style_hover" "enum_pages_blocks_related_posts_hover" DEFAULT 'lift',
      "style_bg" "enum_pages_blocks_related_posts_bg" DEFAULT 'none',
      "style_gap" "enum_pages_blocks_related_posts_gap" DEFAULT '24',
      "show_all_link" boolean DEFAULT false,
      "all_link_url" varchar,
      "block_name" varchar
    );

    CREATE TABLE IF NOT EXISTS "pages_blocks_related_posts_block_locales" (
      "title" varchar DEFAULT 'Das könnte Sie auch interessieren',
      "all_link_text" varchar DEFAULT 'Alle Artikel anzeigen',
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL
    );

    -- Posts relationship for manual selection
    CREATE TABLE IF NOT EXISTS "pages_blocks_related_posts_block_rels" (
      "id" serial PRIMARY KEY NOT NULL,
      "order" integer,
      "parent_id" varchar NOT NULL,
      "path" varchar NOT NULL,
      "posts_id" integer
    );

    ALTER TABLE "pages_blocks_related_posts_block"
      ADD CONSTRAINT "pages_blocks_related_posts_block_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_related_posts_block"
      ADD CONSTRAINT "pages_blocks_related_posts_block_category_id_fk"
      FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE set null ON UPDATE no action;

    ALTER TABLE "pages_blocks_related_posts_block"
      ADD CONSTRAINT "pages_blocks_related_posts_block_tag_id_fk"
      FOREIGN KEY ("tag_id") REFERENCES "public"."tags"("id") ON DELETE set null ON UPDATE no action;

    ALTER TABLE "pages_blocks_related_posts_block_locales"
      ADD CONSTRAINT "pages_blocks_related_posts_block_locales_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_related_posts_block"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_related_posts_block_rels"
      ADD CONSTRAINT "pages_blocks_related_posts_block_rels_parent_fk"
      FOREIGN KEY ("parent_id") REFERENCES "public"."pages_blocks_related_posts_block"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_related_posts_block_rels"
      ADD CONSTRAINT "pages_blocks_related_posts_block_rels_posts_fk"
      FOREIGN KEY ("posts_id") REFERENCES "public"."posts"("id") ON DELETE cascade ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "pages_blocks_related_posts_block_order_idx"
      ON "pages_blocks_related_posts_block" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "pages_blocks_related_posts_block_parent_id_idx"
      ON "pages_blocks_related_posts_block" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "pages_blocks_related_posts_block_path_idx"
      ON "pages_blocks_related_posts_block" USING btree ("_path");

    CREATE UNIQUE INDEX IF NOT EXISTS "pages_blocks_related_posts_block_locales_locale_parent_id_unique"
      ON "pages_blocks_related_posts_block_locales" USING btree ("_locale", "_parent_id");
  `)

  // ========================================
  // ShareButtonsBlock
  // ========================================
  await db.execute(sql`
    -- Enums for ShareButtonsBlock
    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_layout" AS ENUM('horizontal', 'vertical', 'floating', 'sticky');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_align" AS ENUM('left', 'center', 'right');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_float_side" AS ENUM('left', 'right');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_variant" AS ENUM('filled', 'outline', 'icon', 'minimal');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_size" AS ENUM('sm', 'md', 'lg');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_shape" AS ENUM('square', 'rounded', 'circle', 'pill');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_color" AS ENUM('brand', 'gray', 'dark', 'light', 'accent');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_share_gap" AS ENUM('0', '4', '8', '12');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "pages_blocks_share_buttons_block" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL,
      "_path" text NOT NULL,
      "id" varchar PRIMARY KEY NOT NULL,
      "platforms_facebook" boolean DEFAULT true,
      "platforms_twitter" boolean DEFAULT true,
      "platforms_linkedin" boolean DEFAULT true,
      "platforms_xing" boolean DEFAULT false,
      "platforms_whatsapp" boolean DEFAULT true,
      "platforms_telegram" boolean DEFAULT false,
      "platforms_email" boolean DEFAULT true,
      "platforms_copy" boolean DEFAULT true,
      "platforms_print" boolean DEFAULT false,
      "platforms_pinterest" boolean DEFAULT false,
      "platforms_reddit" boolean DEFAULT false,
      "layout" "enum_pages_blocks_share_layout" DEFAULT 'horizontal',
      "align" "enum_pages_blocks_share_align" DEFAULT 'left',
      "float_side" "enum_pages_blocks_share_float_side" DEFAULT 'left',
      "style_variant" "enum_pages_blocks_share_variant" DEFAULT 'filled',
      "style_size" "enum_pages_blocks_share_size" DEFAULT 'md',
      "style_shape" "enum_pages_blocks_share_shape" DEFAULT 'rounded',
      "style_color_scheme" "enum_pages_blocks_share_color" DEFAULT 'brand',
      "style_gap" "enum_pages_blocks_share_gap" DEFAULT '8',
      "style_show_label" boolean DEFAULT false,
      "style_show_count" boolean DEFAULT false,
      "behavior_open_in_popup" boolean DEFAULT true,
      "behavior_use_native_share" boolean DEFAULT true,
      "content_hashtags" varchar,
      "content_via" varchar,
      "block_name" varchar
    );

    CREATE TABLE IF NOT EXISTS "pages_blocks_share_buttons_block_locales" (
      "label" varchar,
      "behavior_copy_feedback" varchar DEFAULT 'Link kopiert!',
      "content_custom_title" varchar,
      "content_custom_description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL
    );

    ALTER TABLE "pages_blocks_share_buttons_block"
      ADD CONSTRAINT "pages_blocks_share_buttons_block_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_share_buttons_block_locales"
      ADD CONSTRAINT "pages_blocks_share_buttons_block_locales_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_share_buttons_block"("id") ON DELETE cascade ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "pages_blocks_share_buttons_block_order_idx"
      ON "pages_blocks_share_buttons_block" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "pages_blocks_share_buttons_block_parent_id_idx"
      ON "pages_blocks_share_buttons_block" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "pages_blocks_share_buttons_block_path_idx"
      ON "pages_blocks_share_buttons_block" USING btree ("_path");

    CREATE UNIQUE INDEX IF NOT EXISTS "pages_blocks_share_buttons_block_locales_locale_parent_id_unique"
      ON "pages_blocks_share_buttons_block_locales" USING btree ("_locale", "_parent_id");
  `)

  // ========================================
  // TableOfContentsBlock
  // ========================================
  await db.execute(sql`
    -- Enums for TableOfContentsBlock
    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_layout" AS ENUM('list', 'numbered', 'inline', 'sidebar', 'dropdown');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_sidebar_pos" AS ENUM('left', 'right');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_progress_style" AS ENUM('bar', 'percent', 'circle');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_bg" AS ENUM('none', 'light', 'dark', 'accent');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_border_side" AS ENUM('all', 'left', 'top');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_rounded" AS ENUM('none', 'sm', 'md', 'lg');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_font_size" AS ENUM('sm', 'base', 'lg');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;

    DO $$
    BEGIN
      CREATE TYPE "enum_pages_blocks_toc_line_height" AS ENUM('tight', 'normal', 'relaxed');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "pages_blocks_toc_block" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL,
      "_path" text NOT NULL,
      "id" varchar PRIMARY KEY NOT NULL,
      "levels_h2" boolean DEFAULT true,
      "levels_h3" boolean DEFAULT true,
      "levels_h4" boolean DEFAULT false,
      "levels_h5" boolean DEFAULT false,
      "levels_h6" boolean DEFAULT false,
      "layout" "enum_pages_blocks_toc_layout" DEFAULT 'list',
      "sidebar_pos" "enum_pages_blocks_toc_sidebar_pos" DEFAULT 'right',
      "behavior_smooth_scroll" boolean DEFAULT true,
      "behavior_highlight_active" boolean DEFAULT true,
      "behavior_scroll_offset" integer DEFAULT 80,
      "behavior_collapsible" boolean DEFAULT false,
      "behavior_start_collapsed" boolean DEFAULT false,
      "behavior_show_progress" boolean DEFAULT false,
      "behavior_progress_style" "enum_pages_blocks_toc_progress_style" DEFAULT 'bar',
      "style_bg" "enum_pages_blocks_toc_bg" DEFAULT 'light',
      "style_border" boolean DEFAULT true,
      "style_border_side" "enum_pages_blocks_toc_border_side" DEFAULT 'left',
      "style_rounded" "enum_pages_blocks_toc_rounded" DEFAULT 'md',
      "style_shadow" boolean DEFAULT false,
      "style_indent" boolean DEFAULT true,
      "style_show_icon" boolean DEFAULT false,
      "style_font_size" "enum_pages_blocks_toc_font_size" DEFAULT 'sm',
      "style_line_height" "enum_pages_blocks_toc_line_height" DEFAULT 'relaxed',
      "min_items" integer DEFAULT 3,
      "max_items" integer,
      "block_name" varchar
    );

    CREATE TABLE IF NOT EXISTS "pages_blocks_toc_block_locales" (
      "title" varchar DEFAULT 'Inhaltsverzeichnis',
      "a11y_label" varchar DEFAULT 'Inhaltsverzeichnis',
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL
    );

    ALTER TABLE "pages_blocks_toc_block"
      ADD CONSTRAINT "pages_blocks_toc_block_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;

    ALTER TABLE "pages_blocks_toc_block_locales"
      ADD CONSTRAINT "pages_blocks_toc_block_locales_parent_id_fk"
      FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_toc_block"("id") ON DELETE cascade ON UPDATE no action;

    CREATE INDEX IF NOT EXISTS "pages_blocks_toc_block_order_idx"
      ON "pages_blocks_toc_block" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "pages_blocks_toc_block_parent_id_idx"
      ON "pages_blocks_toc_block" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "pages_blocks_toc_block_path_idx"
      ON "pages_blocks_toc_block" USING btree ("_path");

    CREATE UNIQUE INDEX IF NOT EXISTS "pages_blocks_toc_block_locales_locale_parent_id_unique"
      ON "pages_blocks_toc_block_locales" USING btree ("_locale", "_parent_id");
  `)
}

export async function down({ db }: MigrateDownArgs): Promise<void> {
  // Drop Blocks
  await db.execute(sql`
    DROP TABLE IF EXISTS "pages_blocks_toc_block_locales" CASCADE;
    DROP TABLE IF EXISTS "pages_blocks_toc_block" CASCADE;

    DROP TABLE IF EXISTS "pages_blocks_share_buttons_block_locales" CASCADE;
    DROP TABLE IF EXISTS "pages_blocks_share_buttons_block" CASCADE;

    DROP TABLE IF EXISTS "pages_blocks_related_posts_block_rels" CASCADE;
    DROP TABLE IF EXISTS "pages_blocks_related_posts_block_locales" CASCADE;
    DROP TABLE IF EXISTS "pages_blocks_related_posts_block" CASCADE;

    DROP TABLE IF EXISTS "pages_blocks_author_bio_block_rels" CASCADE;
    DROP TABLE IF EXISTS "pages_blocks_author_bio_block_locales" CASCADE;
    DROP TABLE IF EXISTS "pages_blocks_author_bio_block" CASCADE;
  `)

  // Drop Block Enums
  await db.execute(sql`
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_line_height";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_font_size";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_rounded";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_border_side";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_bg";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_progress_style";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_sidebar_pos";
    DROP TYPE IF EXISTS "enum_pages_blocks_toc_layout";

    DROP TYPE IF EXISTS "enum_pages_blocks_share_gap";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_color";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_shape";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_size";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_variant";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_float_side";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_align";
    DROP TYPE IF EXISTS "enum_pages_blocks_share_layout";

    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_gap";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_bg";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_hover";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_rounded";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_img_ratio";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_cols";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_layout";
    DROP TYPE IF EXISTS "enum_pages_blocks_related_posts_source";

    DROP TYPE IF EXISTS "enum_pages_blocks_author_bio_bg";
    DROP TYPE IF EXISTS "enum_pages_blocks_author_bio_avatar_shape";
    DROP TYPE IF EXISTS "enum_pages_blocks_author_bio_avatar_size";
    DROP TYPE IF EXISTS "enum_pages_blocks_author_bio_show_bio";
    DROP TYPE IF EXISTS "enum_pages_blocks_author_bio_layout";
    DROP TYPE IF EXISTS "enum_pages_blocks_author_bio_source";
  `)

  // Drop Posts extensions
  await db.execute(sql`
    ALTER TABLE "posts" DROP COLUMN IF EXISTS "author_id";
    ALTER TABLE "posts" DROP COLUMN IF EXISTS "author_legacy";
    ALTER TABLE "posts" DROP COLUMN IF EXISTS "reading_time";
    ALTER TABLE "posts_rels" DROP COLUMN IF EXISTS "authors_id";
    ALTER TABLE "posts_rels" DROP COLUMN IF EXISTS "tags_id";
  `)

  // Drop Authors
  await db.execute(sql`
    DROP TABLE IF EXISTS "authors_locales" CASCADE;
    DROP TABLE IF EXISTS "authors" CASCADE;
  `)

  // Drop Tags
  await db.execute(sql`
    DROP TABLE IF EXISTS "tags_locales" CASCADE;
    DROP TABLE IF EXISTS "tags" CASCADE;
  `)
}
