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

/**
 * Migration for tenant-specific collections:
 * - Bookings (porwoll.de)
 * - Certifications (C2S)
 * - Projects (gunshin)
 */

export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
  // ========================================
  // BOOKINGS COLLECTION (porwoll.de)
  // ========================================

  // Create enums for bookings
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_service_type" AS ENUM('wedding', 'portrait', 'business', 'event', 'product', 'family', 'newborn', 'maternity', 'realestate', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_duration" AS ENUM('30', '60', '120', '180', '240', '480', 'custom');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_location_type" AS ENUM('studio', 'outdoor', 'customer', 'event', 'tbd');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_status" AS ENUM('pending', 'review', 'confirmed', 'deposit', 'completed', 'cancelled', 'noshow');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_priority" AS ENUM('high', 'normal', 'low');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_source" AS ENUM('website', 'phone', 'email', 'instagram', 'facebook', 'referral', 'returning', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_bookings_contact_history_type" AS ENUM('email_sent', 'email_received', 'call', 'whatsapp', 'inperson');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  // Create bookings table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "bookings" (
      "id" serial PRIMARY KEY NOT NULL,
      "tenant_id" integer REFERENCES "tenants"("id") ON DELETE SET NULL,
      "customer_name" varchar NOT NULL,
      "customer_email" varchar NOT NULL,
      "customer_phone" varchar,
      "customer_company" varchar,
      "service_type" "enum_bookings_service_type" NOT NULL,
      "service_id" integer REFERENCES "services"("id") ON DELETE SET NULL,
      "date" timestamp(3) with time zone NOT NULL,
      "time" varchar,
      "duration" "enum_bookings_duration",
      "location_type" "enum_bookings_location_type",
      "location_address" varchar,
      "participants" numeric,
      "message" varchar,
      "status" "enum_bookings_status" NOT NULL DEFAULT 'pending',
      "priority" "enum_bookings_priority" DEFAULT 'normal',
      "pricing_estimated_price" numeric,
      "pricing_final_price" numeric,
      "pricing_deposit_amount" numeric,
      "pricing_deposit_paid" boolean DEFAULT false,
      "pricing_fully_paid" boolean DEFAULT false,
      "assigned_to_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
      "source" "enum_bookings_source",
      "gdpr_consent" 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
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_tenant_idx" ON "bookings" USING btree ("tenant_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_service_idx" ON "bookings" USING btree ("service_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_assigned_to_idx" ON "bookings" USING btree ("assigned_to_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_updated_at_idx" ON "bookings" USING btree ("updated_at");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_created_at_idx" ON "bookings" USING btree ("created_at");`)

  // Create bookings_reference_images table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "bookings_reference_images" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "bookings"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "image_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "note" varchar
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_reference_images_order_idx" ON "bookings_reference_images" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_reference_images_parent_id_idx" ON "bookings_reference_images" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_reference_images_image_idx" ON "bookings_reference_images" USING btree ("image_id");`)

  // Create bookings_internal_notes table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "bookings_internal_notes" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "bookings"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "note" varchar NOT NULL,
      "author_id" integer REFERENCES "users"("id") ON DELETE SET NULL,
      "created_at" timestamp(3) with time zone
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_internal_notes_order_idx" ON "bookings_internal_notes" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_internal_notes_parent_id_idx" ON "bookings_internal_notes" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_internal_notes_author_idx" ON "bookings_internal_notes" USING btree ("author_id");`)

  // Create bookings_contact_history table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "bookings_contact_history" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "bookings"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "type" "enum_bookings_contact_history_type" NOT NULL,
      "summary" varchar NOT NULL,
      "date" timestamp(3) with time zone
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_contact_history_order_idx" ON "bookings_contact_history" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "bookings_contact_history_parent_id_idx" ON "bookings_contact_history" USING btree ("_parent_id");`)

  // ========================================
  // CERTIFICATIONS COLLECTION (C2S)
  // ========================================

  // Create enums for certifications
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_type" AS ENUM('iso', 'din', 'accreditation', 'seal', 'membership', 'award', 'license', 'approval', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_category" AS ENUM('quality', 'care', 'medical', 'hygiene', 'safety', 'privacy', 'environment', 'hr', 'it-security', 'accessibility', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_issuer_country" AS ENUM('DE', 'AT', 'CH', 'EU', 'INT');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_renewal_cycle" AS ENUM('yearly', '2years', '3years', '5years', 'unlimited');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_status" AS ENUM('active', 'pending', 'renewal', 'suspended', 'expired', 'withdrawn');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_visibility" AS ENUM('public', 'request', 'internal');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_benefits_icon" AS ENUM('check', 'star', 'shield', 'heart', 'lock', 'search', 'clock', 'document');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_audits_type" AS ENUM('initial', 'surveillance', 'recertification', 'special');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_certifications_audits_result" AS ENUM('passed', 'conditional', 'failed');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  // Create certifications table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications" (
      "id" serial PRIMARY KEY NOT NULL,
      "tenant_id" integer REFERENCES "tenants"("id") ON DELETE SET NULL,
      "slug" varchar NOT NULL,
      "type" "enum_certifications_type" NOT NULL,
      "category" "enum_certifications_category",
      "issuer_name" varchar NOT NULL,
      "issuer_logo_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "issuer_website" varchar,
      "issuer_country" "enum_certifications_issuer_country",
      "cert_number" varchar,
      "issued_date" timestamp(3) with time zone,
      "valid_until" timestamp(3) with time zone,
      "renewal_cycle" "enum_certifications_renewal_cycle",
      "logo_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "certificate_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "status" "enum_certifications_status" NOT NULL DEFAULT 'active',
      "visibility" "enum_certifications_visibility" DEFAULT 'public',
      "priority" numeric DEFAULT 0,
      "show_on_homepage" 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
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_tenant_idx" ON "certifications" USING btree ("tenant_id");`)
  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "certifications_slug_idx" ON "certifications" USING btree ("slug");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_issuer_logo_idx" ON "certifications" USING btree ("issuer_logo_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_logo_idx" ON "certifications" USING btree ("logo_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_certificate_idx" ON "certifications" USING btree ("certificate_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_updated_at_idx" ON "certifications" USING btree ("updated_at");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_created_at_idx" ON "certifications" USING btree ("created_at");`)

  // Create certifications_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_locales" (
      "name" varchar NOT NULL,
      "description" jsonb,
      "short_description" varchar,
      "scope_description" varchar,
      "seo_meta_title" varchar,
      "seo_meta_description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "certifications"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "certifications_locales_locale_parent_id_unique" ON "certifications_locales" USING btree ("_locale", "_parent_id");`)

  // Create certifications_gallery table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_gallery" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "certifications"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "document_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "title" varchar
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_gallery_order_idx" ON "certifications_gallery" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_gallery_parent_id_idx" ON "certifications_gallery" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_gallery_document_idx" ON "certifications_gallery" USING btree ("document_id");`)

  // Create certifications_requirements table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_requirements" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "certifications"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_requirements_order_idx" ON "certifications_requirements" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_requirements_parent_id_idx" ON "certifications_requirements" USING btree ("_parent_id");`)

  // Create certifications_requirements_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_requirements_locales" (
      "requirement" varchar NOT NULL,
      "description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL REFERENCES "certifications_requirements"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "certifications_requirements_locales_locale_parent_id_unique" ON "certifications_requirements_locales" USING btree ("_locale", "_parent_id");`)

  // Create certifications_benefits table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_benefits" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "certifications"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "icon" "enum_certifications_benefits_icon"
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_benefits_order_idx" ON "certifications_benefits" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_benefits_parent_id_idx" ON "certifications_benefits" USING btree ("_parent_id");`)

  // Create certifications_benefits_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_benefits_locales" (
      "title" varchar NOT NULL,
      "description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL REFERENCES "certifications_benefits"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "certifications_benefits_locales_locale_parent_id_unique" ON "certifications_benefits_locales" USING btree ("_locale", "_parent_id");`)

  // Create certifications_audits table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_audits" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "certifications"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "date" timestamp(3) with time zone NOT NULL,
      "type" "enum_certifications_audits_type",
      "result" "enum_certifications_audits_result",
      "notes" varchar
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_audits_order_idx" ON "certifications_audits" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_audits_parent_id_idx" ON "certifications_audits" USING btree ("_parent_id");`)

  // Create certifications_rels table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "certifications_rels" (
      "id" serial PRIMARY KEY NOT NULL,
      "order" integer,
      "parent_id" integer NOT NULL REFERENCES "certifications"("id") ON DELETE CASCADE,
      "path" varchar NOT NULL,
      "locations_id" integer REFERENCES "locations"("id") ON DELETE CASCADE,
      "services_id" integer REFERENCES "services"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_rels_order_idx" ON "certifications_rels" USING btree ("order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_rels_parent_idx" ON "certifications_rels" USING btree ("parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_rels_path_idx" ON "certifications_rels" USING btree ("path");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_rels_locations_id_idx" ON "certifications_rels" USING btree ("locations_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "certifications_rels_services_id_idx" ON "certifications_rels" USING btree ("services_id");`)

  // ========================================
  // PROJECTS COLLECTION (gunshin)
  // ========================================

  // Create enums for projects
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_type" AS ENUM('game', 'demo', 'mod', 'tool', 'assets', 'prototype', 'gamejam', 'tutorial', 'opensource', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_genres" AS ENUM('action', 'adventure', 'rpg', 'strategy', 'simulation', 'puzzle', 'horror', 'shooter', 'platformer', 'racing', 'sports', 'fighting', 'music', 'visualnovel', 'survival', 'sandbox', 'towerdefense', 'roguelike', 'indie');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_platforms" AS ENUM('windows', 'macos', 'linux', 'web', 'ios', 'android', 'playstation', 'xbox', 'switch', 'steamdeck', 'vr');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_tech_stack_engine" AS ENUM('unity', 'unreal', 'godot', 'gamemaker', 'rpgmaker', 'construct', 'custom', 'renpy', 'phaser', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_tech_stack_languages" AS ENUM('csharp', 'cpp', 'gdscript', 'javascript', 'typescript', 'python', 'lua', 'rust', 'blueprint');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_videos_type" AS ENUM('trailer', 'gameplay', 'devlog', 'tutorial', 'other');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_downloads_platform" AS ENUM('windows', 'macos', 'linux', 'universal');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_status" AS ENUM('development', 'earlyaccess', 'released', 'paused', 'cancelled', 'completed');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "public"."enum_projects_visibility" AS ENUM('public', 'draft', 'unlisted', 'private');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  // Create projects table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects" (
      "id" serial PRIMARY KEY NOT NULL,
      "tenant_id" integer REFERENCES "tenants"("id") ON DELETE SET NULL,
      "slug" varchar NOT NULL,
      "type" "enum_projects_type" NOT NULL,
      "featured_image_id" integer NOT NULL REFERENCES "media"("id") ON DELETE SET NULL,
      "logo_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "tech_stack_engine" "enum_projects_tech_stack_engine",
      "tech_stack_tools" varchar,
      "requirements_minimum_os" varchar,
      "requirements_minimum_cpu" varchar,
      "requirements_minimum_ram" varchar,
      "requirements_minimum_gpu" varchar,
      "requirements_minimum_storage" varchar,
      "requirements_recommended_os" varchar,
      "requirements_recommended_cpu" varchar,
      "requirements_recommended_ram" varchar,
      "requirements_recommended_gpu" varchar,
      "requirements_recommended_storage" varchar,
      "release_date" timestamp(3) with time zone,
      "links_website" varchar,
      "links_steam" varchar,
      "links_itchio" varchar,
      "links_epic_games" varchar,
      "links_gog" varchar,
      "links_play_store" varchar,
      "links_app_store" varchar,
      "links_github" varchar,
      "links_discord" varchar,
      "links_twitter" varchar,
      "game_jam_jam_name" varchar,
      "game_jam_theme" varchar,
      "game_jam_duration" varchar,
      "game_jam_ranking" varchar,
      "game_jam_jam_link" varchar,
      "status" "enum_projects_status" NOT NULL DEFAULT 'development',
      "visibility" "enum_projects_visibility" DEFAULT 'public',
      "featured" boolean DEFAULT false,
      "sort_order" numeric DEFAULT 0,
      "seo_og_image_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
      "created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_tenant_idx" ON "projects" USING btree ("tenant_id");`)
  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "projects_slug_idx" ON "projects" USING btree ("slug");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_featured_image_idx" ON "projects" USING btree ("featured_image_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_logo_idx" ON "projects" USING btree ("logo_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_seo_og_image_idx" ON "projects" USING btree ("seo_og_image_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_updated_at_idx" ON "projects" USING btree ("updated_at");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_created_at_idx" ON "projects" USING btree ("created_at");`)

  // Create projects_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_locales" (
      "title" varchar NOT NULL,
      "tagline" varchar,
      "description" jsonb,
      "short_description" varchar,
      "seo_meta_title" varchar,
      "seo_meta_description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "projects_locales_locale_parent_id_unique" ON "projects_locales" USING btree ("_locale", "_parent_id");`)

  // Create projects_genres table (many-to-many via select)
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_genres" (
      "order" integer NOT NULL,
      "parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "value" "enum_projects_genres",
      "id" serial PRIMARY KEY NOT NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_genres_order_idx" ON "projects_genres" USING btree ("order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_genres_parent_idx" ON "projects_genres" USING btree ("parent_id");`)

  // Create projects_platforms table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_platforms" (
      "order" integer NOT NULL,
      "parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "value" "enum_projects_platforms",
      "id" serial PRIMARY KEY NOT NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_platforms_order_idx" ON "projects_platforms" USING btree ("order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_platforms_parent_idx" ON "projects_platforms" USING btree ("parent_id");`)

  // Create projects_tech_stack_languages table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_tech_stack_languages" (
      "order" integer NOT NULL,
      "parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "value" "enum_projects_tech_stack_languages",
      "id" serial PRIMARY KEY NOT NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_tech_stack_languages_order_idx" ON "projects_tech_stack_languages" USING btree ("order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_tech_stack_languages_parent_idx" ON "projects_tech_stack_languages" USING btree ("parent_id");`)

  // Create projects_screenshots table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_screenshots" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "image_id" integer NOT NULL REFERENCES "media"("id") ON DELETE SET NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_screenshots_order_idx" ON "projects_screenshots" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_screenshots_parent_id_idx" ON "projects_screenshots" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_screenshots_image_idx" ON "projects_screenshots" USING btree ("image_id");`)

  // Create projects_screenshots_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_screenshots_locales" (
      "caption" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL REFERENCES "projects_screenshots"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "projects_screenshots_locales_locale_parent_id_unique" ON "projects_screenshots_locales" USING btree ("_locale", "_parent_id");`)

  // Create projects_videos table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_videos" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "type" "enum_projects_videos_type" NOT NULL,
      "url" varchar NOT NULL,
      "thumbnail_id" integer REFERENCES "media"("id") ON DELETE SET NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_videos_order_idx" ON "projects_videos" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_videos_parent_id_idx" ON "projects_videos" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_videos_thumbnail_idx" ON "projects_videos" USING btree ("thumbnail_id");`)

  // Create projects_videos_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_videos_locales" (
      "title" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL REFERENCES "projects_videos"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "projects_videos_locales_locale_parent_id_unique" ON "projects_videos_locales" USING btree ("_locale", "_parent_id");`)

  // Create projects_downloads table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_downloads" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "title" varchar NOT NULL,
      "platform" "enum_projects_downloads_platform",
      "version" varchar,
      "file_id" integer REFERENCES "media"("id") ON DELETE SET NULL,
      "external_url" varchar,
      "size" varchar
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_downloads_order_idx" ON "projects_downloads" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_downloads_parent_id_idx" ON "projects_downloads" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_downloads_file_idx" ON "projects_downloads" USING btree ("file_id");`)

  // Create projects_features table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_features" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "icon_id" integer REFERENCES "media"("id") ON DELETE SET NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_features_order_idx" ON "projects_features" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_features_parent_id_idx" ON "projects_features" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_features_icon_idx" ON "projects_features" USING btree ("icon_id");`)

  // Create projects_features_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_features_locales" (
      "title" varchar NOT NULL,
      "description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL REFERENCES "projects_features"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "projects_features_locales_locale_parent_id_unique" ON "projects_features_locales" USING btree ("_locale", "_parent_id");`)

  // Create projects_team table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_team" (
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "id" varchar PRIMARY KEY NOT NULL,
      "name" varchar NOT NULL,
      "link" varchar,
      "avatar_id" integer REFERENCES "media"("id") ON DELETE SET NULL
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_team_order_idx" ON "projects_team" USING btree ("_order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_team_parent_id_idx" ON "projects_team" USING btree ("_parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_team_avatar_idx" ON "projects_team" USING btree ("avatar_id");`)

  // Create projects_team_locales table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_team_locales" (
      "role" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" "_locales" NOT NULL,
      "_parent_id" varchar NOT NULL REFERENCES "projects_team"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "projects_team_locales_locale_parent_id_unique" ON "projects_team_locales" USING btree ("_locale", "_parent_id");`)

  // Create projects_rels table for devlogs relationship
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "projects_rels" (
      "id" serial PRIMARY KEY NOT NULL,
      "order" integer,
      "parent_id" integer NOT NULL REFERENCES "projects"("id") ON DELETE CASCADE,
      "path" varchar NOT NULL,
      "posts_id" integer REFERENCES "posts"("id") ON DELETE CASCADE
    );
  `)

  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_rels_order_idx" ON "projects_rels" USING btree ("order");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_rels_parent_idx" ON "projects_rels" USING btree ("parent_id");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_rels_path_idx" ON "projects_rels" USING btree ("path");`)
  await db.execute(sql`CREATE INDEX IF NOT EXISTS "projects_rels_posts_id_idx" ON "projects_rels" USING btree ("posts_id");`)
}

export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
  // Drop projects tables
  await db.execute(sql`DROP TABLE IF EXISTS "projects_rels" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_team_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_team" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_features_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_features" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_downloads" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_videos_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_videos" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_screenshots_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_screenshots" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_tech_stack_languages" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_platforms" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_genres" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "projects" CASCADE;`)

  // Drop certifications tables
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_rels" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_audits" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_benefits_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_benefits" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_requirements_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_requirements" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_gallery" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications_locales" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "certifications" CASCADE;`)

  // Drop bookings tables
  await db.execute(sql`DROP TABLE IF EXISTS "bookings_contact_history" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "bookings_internal_notes" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "bookings_reference_images" CASCADE;`)
  await db.execute(sql`DROP TABLE IF EXISTS "bookings" CASCADE;`)

  // Drop projects enums
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_visibility" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_status" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_downloads_platform" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_videos_type" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_tech_stack_languages" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_tech_stack_engine" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_platforms" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_genres" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_projects_type" CASCADE;`)

  // Drop certifications enums
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_audits_result" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_audits_type" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_benefits_icon" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_visibility" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_status" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_renewal_cycle" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_issuer_country" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_category" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_certifications_type" CASCADE;`)

  // Drop bookings enums
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_contact_history_type" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_source" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_priority" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_status" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_location_type" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_duration" CASCADE;`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_bookings_service_type" CASCADE;`)
}
