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

/**
 * Migration: Add YouTube Operations Hub v2 Collections
 *
 * This migration creates:
 * - yt_batches table with arrays (shootDays, seriesDistribution)
 * - yt_monthly_goals table with arrays (customGoals)
 * - yt_script_tpl table (Script Templates) with blocks
 * - yt_checklist_templates table with items array
 * - Extends youtube_content with production, script, posting fields
 * - Adds columns to payload_locked_documents_rels for all 4 new collections
 */
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
  // ===== ENUMS =====

  // YtBatches enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_batches_shoot_days_location" AS ENUM ('home', 'office', 'mobile', 'external');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_batches_shoot_days_duration" AS ENUM ('2h', '4h', '8h');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

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

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_batches_status" AS ENUM ('planning', 'scripting', 'production', 'editing', 'review', 'ready', 'published');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  // YtMonthlyGoals enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_monthly_goals_custom_status" AS ENUM ('on_track', 'at_risk', 'achieved', 'missed');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  // YtScriptTemplates enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_script_tpl_format" AS ENUM ('short', 'longform');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  // ScriptSectionBlock enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_script_sec_type" AS ENUM ('hook', 'intro_ident', 'context', 'content_part', 'summary', 'cta', 'outro', 'disclaimer');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_script_sec_ovl_style" AS ENUM ('standard', 'highlight', 'quote', 'statistic', 'list');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  // YtChecklistTemplates enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_checklist_tpl_type" AS ENUM ('upload', 'production', 'review', 'post_publish');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_checklist_tpl_format" AS ENUM ('all', 'short', 'longform');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_yt_checklist_tpl_items_category" AS ENUM ('metadata', 'assets', 'seo', 'community', 'legal', 'other');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  // YouTubeContent posting enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_youtube_content_cta_type" AS ENUM ('link_in_bio', 'newsletter', 'longform_link', 'custom');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_youtube_content_disclaimer_type" AS ENUM ('medical', 'legal', 'affiliate', 'sponsored');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_youtube_content_disclaimer_placement" AS ENUM ('spoken', 'overlay', 'description', 'all');
    EXCEPTION WHEN duplicate_object THEN null;
    END $$;
  `)

  // ===== YT_BATCHES TABLE =====
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_batches" (
      "id" serial PRIMARY KEY NOT NULL,
      "name" varchar NOT NULL,
      "channel_id" integer NOT NULL REFERENCES youtube_channels(id) ON DELETE SET NULL,
      "production_period_start" timestamp(3) with time zone NOT NULL,
      "production_period_end" timestamp(3) with time zone NOT NULL,
      "targets_shorts_target" numeric DEFAULT 7 NOT NULL,
      "targets_longforms_target" numeric DEFAULT 3 NOT NULL,
      "targets_total_target" numeric,
      "targets_buffer_days" numeric DEFAULT 3,
      "status" "enum_yt_batches_status" DEFAULT 'planning' NOT NULL,
      "progress_shorts_completed" numeric DEFAULT 0,
      "progress_longforms_completed" numeric DEFAULT 0,
      "progress_percentage" numeric DEFAULT 0,
      "team_producer_id" integer REFERENCES users(id) ON DELETE SET NULL,
      "team_editor_id" integer REFERENCES users(id) ON DELETE SET NULL,
      "team_reviewer_id" integer REFERENCES users(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 TABLE IF NOT EXISTS "yt_batches_locales" (
      "notes" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_batches(id) ON DELETE CASCADE,
      CONSTRAINT "yt_batches_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_batches_shoot_days" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_batches(id) ON DELETE CASCADE,
      "date" timestamp(3) with time zone NOT NULL,
      "location" "enum_yt_batches_shoot_days_location",
      "duration" "enum_yt_batches_shoot_days_duration",
      "notes" varchar
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_batches_series_distribution" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_batches(id) ON DELETE CASCADE,
      "series" varchar NOT NULL,
      "shorts_count" numeric DEFAULT 0,
      "longforms_count" numeric DEFAULT 0,
      "priority" "enum_yt_batches_series_dist_priority" DEFAULT 'normal'
    );
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "yt_batches_channel_idx" ON "yt_batches" USING btree ("channel_id");
    CREATE INDEX IF NOT EXISTS "yt_batches_status_idx" ON "yt_batches" USING btree ("status");
    CREATE INDEX IF NOT EXISTS "yt_batches_producer_idx" ON "yt_batches" USING btree ("team_producer_id");
    CREATE INDEX IF NOT EXISTS "yt_batches_editor_idx" ON "yt_batches" USING btree ("team_editor_id");
    CREATE INDEX IF NOT EXISTS "yt_batches_reviewer_idx" ON "yt_batches" USING btree ("team_reviewer_id");
    CREATE INDEX IF NOT EXISTS "yt_batches_updated_at_idx" ON "yt_batches" USING btree ("updated_at");
    CREATE INDEX IF NOT EXISTS "yt_batches_created_at_idx" ON "yt_batches" USING btree ("created_at");
    CREATE INDEX IF NOT EXISTS "yt_batches_locales_locale_idx" ON "yt_batches_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yt_batches_locales_parent_idx" ON "yt_batches_locales" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_batches_shoot_days_order_idx" ON "yt_batches_shoot_days" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_batches_shoot_days_parent_idx" ON "yt_batches_shoot_days" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_batches_series_dist_order_idx" ON "yt_batches_series_distribution" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_batches_series_dist_parent_idx" ON "yt_batches_series_distribution" USING btree ("_parent_id");
  `)

  // ===== YT_MONTHLY_GOALS TABLE =====
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_monthly_goals" (
      "id" serial PRIMARY KEY NOT NULL,
      "channel_id" integer NOT NULL REFERENCES youtube_channels(id) ON DELETE SET NULL,
      "month" timestamp(3) with time zone NOT NULL,
      "display_title" varchar,
      "content_goals_longforms_target" numeric DEFAULT 12,
      "content_goals_longforms_current" numeric DEFAULT 0,
      "content_goals_shorts_target" numeric DEFAULT 28,
      "content_goals_shorts_current" numeric DEFAULT 0,
      "audience_goals_subscribers_target" numeric,
      "audience_goals_subscribers_current" numeric,
      "audience_goals_views_target" numeric,
      "audience_goals_views_current" numeric,
      "engagement_goals_avg_ctr_target" varchar,
      "engagement_goals_avg_ctr_current" varchar,
      "engagement_goals_avg_retention_target" varchar,
      "engagement_goals_avg_retention_current" varchar,
      "business_goals_newsletter_signups_target" numeric,
      "business_goals_newsletter_signups_current" numeric,
      "business_goals_affiliate_revenue_target" numeric,
      "business_goals_affiliate_revenue_current" numeric,
      "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 TABLE IF NOT EXISTS "yt_monthly_goals_locales" (
      "notes" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_monthly_goals(id) ON DELETE CASCADE,
      CONSTRAINT "yt_monthly_goals_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_monthly_goals_custom_goals" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_monthly_goals(id) ON DELETE CASCADE,
      "metric" varchar NOT NULL,
      "target" varchar NOT NULL,
      "current" varchar,
      "status" "enum_yt_monthly_goals_custom_status"
    );
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_channel_idx" ON "yt_monthly_goals" USING btree ("channel_id");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_month_idx" ON "yt_monthly_goals" USING btree ("month");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_updated_at_idx" ON "yt_monthly_goals" USING btree ("updated_at");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_created_at_idx" ON "yt_monthly_goals" USING btree ("created_at");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_locales_locale_idx" ON "yt_monthly_goals_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_locales_parent_idx" ON "yt_monthly_goals_locales" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_custom_order_idx" ON "yt_monthly_goals_custom_goals" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_monthly_goals_custom_parent_idx" ON "yt_monthly_goals_custom_goals" USING btree ("_parent_id");
  `)

  // ===== YT_SCRIPT_TPL TABLE =====
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_script_tpl" (
      "id" serial PRIMARY KEY NOT NULL,
      "channel_id" integer NOT NULL REFERENCES youtube_channels(id) ON DELETE SET NULL,
      "series" varchar NOT NULL,
      "format" "enum_yt_script_tpl_format" NOT 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 TABLE IF NOT EXISTS "yt_script_tpl_locales" (
      "name" varchar NOT NULL,
      "description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_script_tpl(id) ON DELETE CASCADE,
      CONSTRAINT "yt_script_tpl_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_script_tpl_blocks_script_sec" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_script_tpl(id) ON DELETE CASCADE,
      "_path" varchar NOT NULL,
      "sec_type" "enum_script_sec_type" NOT NULL,
      "duration" varchar,
      "section_title" varchar,
      "visual_notes" varchar,
      "block_name" varchar
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_script_tpl_blocks_script_sec_locales" (
      "spoken_text" jsonb,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_script_tpl_blocks_script_sec(id) ON DELETE CASCADE,
      CONSTRAINT "yt_script_tpl_blocks_script_sec_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_script_tpl_blocks_script_sec_b_roll" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_script_tpl_blocks_script_sec(id) ON DELETE CASCADE,
      "instruction" varchar NOT NULL,
      "timestamp" varchar
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_script_tpl_blocks_script_sec_overlays" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_script_tpl_blocks_script_sec(id) ON DELETE CASCADE,
      "text" varchar NOT NULL,
      "ovl_style" "enum_script_sec_ovl_style" DEFAULT 'standard'
    );
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_channel_idx" ON "yt_script_tpl" USING btree ("channel_id");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_format_idx" ON "yt_script_tpl" USING btree ("format");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_updated_at_idx" ON "yt_script_tpl" USING btree ("updated_at");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_created_at_idx" ON "yt_script_tpl" USING btree ("created_at");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_locales_locale_idx" ON "yt_script_tpl_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_locales_parent_idx" ON "yt_script_tpl_locales" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_blocks_order_idx" ON "yt_script_tpl_blocks_script_sec" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_blocks_parent_idx" ON "yt_script_tpl_blocks_script_sec" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_blocks_path_idx" ON "yt_script_tpl_blocks_script_sec" USING btree ("_path");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_blocks_locales_locale_idx" ON "yt_script_tpl_blocks_script_sec_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_blocks_locales_parent_idx" ON "yt_script_tpl_blocks_script_sec_locales" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_b_roll_order_idx" ON "yt_script_tpl_blocks_script_sec_b_roll" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_b_roll_parent_idx" ON "yt_script_tpl_blocks_script_sec_b_roll" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_overlays_order_idx" ON "yt_script_tpl_blocks_script_sec_overlays" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_script_tpl_overlays_parent_idx" ON "yt_script_tpl_blocks_script_sec_overlays" USING btree ("_parent_id");
  `)

  // ===== YT_CHECKLIST_TEMPLATES TABLE =====
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_checklist_templates" (
      "id" serial PRIMARY KEY NOT NULL,
      "channel_id" integer REFERENCES youtube_channels(id) ON DELETE SET NULL,
      "type" "enum_yt_checklist_tpl_type" NOT NULL,
      "format" "enum_yt_checklist_tpl_format" DEFAULT 'all',
      "is_default" boolean DEFAULT false,
      "is_active" boolean DEFAULT true,
      "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 TABLE IF NOT EXISTS "yt_checklist_templates_locales" (
      "name" varchar NOT NULL,
      "description" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_checklist_templates(id) ON DELETE CASCADE,
      CONSTRAINT "yt_checklist_templates_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_checklist_templates_items" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_checklist_templates(id) ON DELETE CASCADE,
      "order" numeric,
      "category" "enum_yt_checklist_tpl_items_category",
      "is_required" boolean DEFAULT true
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "yt_checklist_templates_items_locales" (
      "task" varchar NOT NULL,
      "details" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES yt_checklist_templates_items(id) ON DELETE CASCADE,
      CONSTRAINT "yt_checklist_templates_items_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_channel_idx" ON "yt_checklist_templates" USING btree ("channel_id");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_type_idx" ON "yt_checklist_templates" USING btree ("type");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_format_idx" ON "yt_checklist_templates" USING btree ("format");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_updated_at_idx" ON "yt_checklist_templates" USING btree ("updated_at");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_created_at_idx" ON "yt_checklist_templates" USING btree ("created_at");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_locales_locale_idx" ON "yt_checklist_templates_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_locales_parent_idx" ON "yt_checklist_templates_locales" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_items_order_idx" ON "yt_checklist_templates_items" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_items_parent_idx" ON "yt_checklist_templates_items" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_items_l_locale_idx" ON "yt_checklist_templates_items_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yt_checklist_tpl_items_l_parent_idx" ON "yt_checklist_templates_items_locales" USING btree ("_parent_id");
  `)

  // ===== EXTEND YOUTUBE_CONTENT TABLE =====

  // Add productionBatch relationship
  await db.execute(sql`
    ALTER TABLE "youtube_content"
      ADD COLUMN IF NOT EXISTS "production_batch_id" integer REFERENCES yt_batches(id) ON DELETE SET NULL;
  `)

  // Add production fields
  await db.execute(sql`
    ALTER TABLE "youtube_content"
      ADD COLUMN IF NOT EXISTS "production_week" numeric,
      ADD COLUMN IF NOT EXISTS "calendar_week" numeric,
      ADD COLUMN IF NOT EXISTS "production_date" timestamp(3) with time zone,
      ADD COLUMN IF NOT EXISTS "target_duration" varchar;
  `)

  // Add posting fields
  await db.execute(sql`
    ALTER TABLE "youtube_content"
      ADD COLUMN IF NOT EXISTS "publish_time" varchar,
      ADD COLUMN IF NOT EXISTS "thumbnail_text" varchar,
      ADD COLUMN IF NOT EXISTS "cta_type" "enum_youtube_content_cta_type",
      ADD COLUMN IF NOT EXISTS "cta_detail" varchar;
  `)

  // Add bRollNotes to locales table
  await db.execute(sql`
    ALTER TABLE "youtube_content_locales"
      ADD COLUMN IF NOT EXISTS "b_roll_notes" varchar;
  `)

  // Create youtube_content_script blocks table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_blocks_script_sec" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content(id) ON DELETE CASCADE,
      "_path" varchar NOT NULL,
      "sec_type" "enum_script_sec_type" NOT NULL,
      "duration" varchar,
      "section_title" varchar,
      "visual_notes" varchar,
      "block_name" varchar
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_blocks_script_sec_locales" (
      "spoken_text" jsonb,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content_blocks_script_sec(id) ON DELETE CASCADE,
      CONSTRAINT "youtube_content_blocks_script_sec_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_blocks_script_sec_b_roll" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content_blocks_script_sec(id) ON DELETE CASCADE,
      "instruction" varchar NOT NULL,
      "timestamp" varchar
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_blocks_script_sec_overlays" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content_blocks_script_sec(id) ON DELETE CASCADE,
      "text" varchar NOT NULL,
      "ovl_style" "enum_script_sec_ovl_style" DEFAULT 'standard'
    );
  `)

  // Create upload checklist array table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_upload_checklist" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content(id) ON DELETE CASCADE,
      "step" varchar NOT NULL,
      "completed" boolean DEFAULT false,
      "completed_at" timestamp(3) with time zone
    );
  `)

  // Create disclaimers array table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_disclaimers" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content(id) ON DELETE CASCADE,
      "type" "enum_youtube_content_disclaimer_type" NOT NULL,
      "placement" "enum_youtube_content_disclaimer_placement"
    );
  `)

  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "youtube_content_disclaimers_locales" (
      "text" varchar,
      "id" serial PRIMARY KEY NOT NULL,
      "_locale" varchar NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES youtube_content_disclaimers(id) ON DELETE CASCADE,
      CONSTRAINT "youtube_content_disclaimers_locales_unique" UNIQUE("_locale", "_parent_id")
    );
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "youtube_content_production_batch_idx" ON "youtube_content" USING btree ("production_batch_id");
    CREATE INDEX IF NOT EXISTS "youtube_content_production_date_idx" ON "youtube_content" USING btree ("production_date");
    CREATE INDEX IF NOT EXISTS "yc_blocks_script_sec_order_idx" ON "youtube_content_blocks_script_sec" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yc_blocks_script_sec_parent_idx" ON "youtube_content_blocks_script_sec" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yc_blocks_script_sec_path_idx" ON "youtube_content_blocks_script_sec" USING btree ("_path");
    CREATE INDEX IF NOT EXISTS "yc_blocks_script_sec_l_locale_idx" ON "youtube_content_blocks_script_sec_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "yc_blocks_script_sec_l_parent_idx" ON "youtube_content_blocks_script_sec_locales" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yc_b_roll_order_idx" ON "youtube_content_blocks_script_sec_b_roll" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yc_b_roll_parent_idx" ON "youtube_content_blocks_script_sec_b_roll" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "yc_overlays_order_idx" ON "youtube_content_blocks_script_sec_overlays" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "yc_overlays_parent_idx" ON "youtube_content_blocks_script_sec_overlays" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "youtube_content_upload_cl_order_idx" ON "youtube_content_upload_checklist" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "youtube_content_upload_cl_parent_idx" ON "youtube_content_upload_checklist" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "youtube_content_discl_order_idx" ON "youtube_content_disclaimers" USING btree ("_order");
    CREATE INDEX IF NOT EXISTS "youtube_content_discl_parent_idx" ON "youtube_content_disclaimers" USING btree ("_parent_id");
    CREATE INDEX IF NOT EXISTS "youtube_content_discl_l_locale_idx" ON "youtube_content_disclaimers_locales" USING btree ("_locale");
    CREATE INDEX IF NOT EXISTS "youtube_content_discl_l_parent_idx" ON "youtube_content_disclaimers_locales" USING btree ("_parent_id");
  `)

  // ===== EXTEND PAYLOAD_LOCKED_DOCUMENTS_RELS =====
  await db.execute(sql`
    ALTER TABLE "payload_locked_documents_rels"
      ADD COLUMN IF NOT EXISTS "yt_batches_id" integer REFERENCES yt_batches(id) ON DELETE CASCADE;
  `)

  await db.execute(sql`
    ALTER TABLE "payload_locked_documents_rels"
      ADD COLUMN IF NOT EXISTS "yt_monthly_goals_id" integer REFERENCES yt_monthly_goals(id) ON DELETE CASCADE;
  `)

  await db.execute(sql`
    ALTER TABLE "payload_locked_documents_rels"
      ADD COLUMN IF NOT EXISTS "yt_script_tpl_id" integer REFERENCES yt_script_tpl(id) ON DELETE CASCADE;
  `)

  await db.execute(sql`
    ALTER TABLE "payload_locked_documents_rels"
      ADD COLUMN IF NOT EXISTS "yt_checklist_templates_id" integer REFERENCES yt_checklist_templates(id) ON DELETE CASCADE;
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_yt_batches_idx"
      ON "payload_locked_documents_rels" USING btree ("yt_batches_id");
    CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_yt_monthly_goals_idx"
      ON "payload_locked_documents_rels" USING btree ("yt_monthly_goals_id");
    CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_yt_script_tpl_idx"
      ON "payload_locked_documents_rels" USING btree ("yt_script_tpl_id");
    CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_yt_checklist_tpl_idx"
      ON "payload_locked_documents_rels" USING btree ("yt_checklist_templates_id");
  `)
}

export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
  // Remove indexes from payload_locked_documents_rels
  await db.execute(sql`DROP INDEX IF EXISTS "payload_locked_documents_rels_yt_batches_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "payload_locked_documents_rels_yt_monthly_goals_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "payload_locked_documents_rels_yt_script_tpl_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "payload_locked_documents_rels_yt_checklist_tpl_idx";`)

  // Remove columns from payload_locked_documents_rels
  await db.execute(sql`ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "yt_batches_id";`)
  await db.execute(sql`ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "yt_monthly_goals_id";`)
  await db.execute(sql`ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "yt_script_tpl_id";`)
  await db.execute(sql`ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "yt_checklist_templates_id";`)

  // Drop youtube_content extension tables
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_disclaimers_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_disclaimers";`)
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_upload_checklist";`)
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_blocks_script_sec_overlays";`)
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_blocks_script_sec_b_roll";`)
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_blocks_script_sec_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "youtube_content_blocks_script_sec";`)

  // Remove columns from youtube_content
  await db.execute(sql`
    ALTER TABLE "youtube_content"
      DROP COLUMN IF EXISTS "production_batch_id",
      DROP COLUMN IF EXISTS "production_week",
      DROP COLUMN IF EXISTS "calendar_week",
      DROP COLUMN IF EXISTS "production_date",
      DROP COLUMN IF EXISTS "target_duration",
      DROP COLUMN IF EXISTS "publish_time",
      DROP COLUMN IF EXISTS "thumbnail_text",
      DROP COLUMN IF EXISTS "cta_type",
      DROP COLUMN IF EXISTS "cta_detail";
  `)

  await db.execute(sql`
    ALTER TABLE "youtube_content_locales"
      DROP COLUMN IF EXISTS "b_roll_notes";
  `)

  // Drop yt_checklist_templates tables
  await db.execute(sql`DROP TABLE IF EXISTS "yt_checklist_templates_items_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_checklist_templates_items";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_checklist_templates_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_checklist_templates";`)

  // Drop yt_script_tpl tables
  await db.execute(sql`DROP TABLE IF EXISTS "yt_script_tpl_blocks_script_sec_overlays";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_script_tpl_blocks_script_sec_b_roll";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_script_tpl_blocks_script_sec_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_script_tpl_blocks_script_sec";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_script_tpl_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_script_tpl";`)

  // Drop yt_monthly_goals tables
  await db.execute(sql`DROP TABLE IF EXISTS "yt_monthly_goals_custom_goals";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_monthly_goals_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_monthly_goals";`)

  // Drop yt_batches tables
  await db.execute(sql`DROP TABLE IF EXISTS "yt_batches_series_distribution";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_batches_shoot_days";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_batches_locales";`)
  await db.execute(sql`DROP TABLE IF EXISTS "yt_batches";`)

  // Drop enums
  await db.execute(sql`DROP TYPE IF EXISTS "enum_youtube_content_disclaimer_placement";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_youtube_content_disclaimer_type";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_youtube_content_cta_type";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_checklist_tpl_items_category";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_checklist_tpl_format";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_checklist_tpl_type";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_script_sec_ovl_style";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_script_sec_type";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_script_tpl_format";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_monthly_goals_custom_status";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_batches_status";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_batches_series_dist_priority";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_batches_shoot_days_duration";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_yt_batches_shoot_days_location";`)
}
