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

/**
 * Migration: Add Report Schedules Collection
 *
 * Creates tables for the scheduled community reports feature.
 */
export async function up({ db }: MigrateUpArgs): Promise<void> {
  // Create enums
  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_report_schedules_frequency" AS ENUM ('daily', 'weekly', 'monthly');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_report_schedules_day_of_week" AS ENUM ('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_report_schedules_report_type" AS ENUM ('overview', 'sentiment_analysis', 'response_metrics', 'content_performance', 'full_report');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_report_schedules_timezone" AS ENUM ('Europe/Berlin', 'Europe/London', 'America/New_York', 'America/Los_Angeles', 'Asia/Tokyo', 'UTC');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  await db.execute(sql`
    DO $$ BEGIN
      CREATE TYPE "enum_report_schedules_format" AS ENUM ('pdf', 'excel', 'html_email');
    EXCEPTION
      WHEN duplicate_object THEN null;
    END $$;
  `)

  // Create main table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "report_schedules" (
      "id" serial PRIMARY KEY NOT NULL,
      "name" varchar NOT NULL,
      "enabled" boolean DEFAULT true,
      "frequency" "enum_report_schedules_frequency" NOT NULL,
      "day_of_week" "enum_report_schedules_day_of_week",
      "day_of_month" numeric,
      "time" varchar DEFAULT '08:00' NOT NULL,
      "timezone" "enum_report_schedules_timezone" DEFAULT 'Europe/Berlin' NOT NULL,
      "report_type" "enum_report_schedules_report_type" DEFAULT 'overview' NOT NULL,
      "period_days" numeric DEFAULT 7,
      "format" "enum_report_schedules_format" DEFAULT 'pdf' NOT NULL,
      "last_sent_at" timestamp(3) with time zone,
      "next_scheduled_at" timestamp(3) with time zone,
      "send_count" numeric DEFAULT 0,
      "last_error" varchar,
      "created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
      "updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL
    );
  `)

  // Create recipients array table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "report_schedules_recipients" (
      "id" serial PRIMARY KEY NOT NULL,
      "_order" integer NOT NULL,
      "_parent_id" integer NOT NULL REFERENCES report_schedules(id) ON DELETE CASCADE,
      "email" varchar NOT NULL,
      "name" varchar
    );
  `)

  // Create channels relationship table
  await db.execute(sql`
    CREATE TABLE IF NOT EXISTS "report_schedules_rels" (
      "id" serial PRIMARY KEY NOT NULL,
      "order" integer,
      "parent_id" integer NOT NULL REFERENCES report_schedules(id) ON DELETE CASCADE,
      "path" varchar NOT NULL,
      "social_accounts_id" integer REFERENCES social_accounts(id) ON DELETE CASCADE
    );
  `)

  // Create indexes
  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "report_schedules_enabled_idx" ON "report_schedules" ("enabled");
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "report_schedules_next_scheduled_idx" ON "report_schedules" ("next_scheduled_at");
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "report_schedules_recipients_parent_idx" ON "report_schedules_recipients" ("_parent_id");
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "report_schedules_rels_parent_idx" ON "report_schedules_rels" ("parent_id");
  `)

  // Add to payload_locked_documents_rels
  await db.execute(sql`
    ALTER TABLE "payload_locked_documents_rels"
    ADD COLUMN IF NOT EXISTS "report_schedules_id" integer
    REFERENCES report_schedules(id) ON DELETE CASCADE;
  `)

  await db.execute(sql`
    CREATE INDEX IF NOT EXISTS "payload_locked_documents_rels_report_schedules_idx"
    ON "payload_locked_documents_rels" ("report_schedules_id");
  `)
}

export async function down({ db }: MigrateDownArgs): Promise<void> {
  // Drop indexes
  await db.execute(sql`DROP INDEX IF EXISTS "payload_locked_documents_rels_report_schedules_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "report_schedules_rels_parent_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "report_schedules_recipients_parent_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "report_schedules_next_scheduled_idx";`)
  await db.execute(sql`DROP INDEX IF EXISTS "report_schedules_enabled_idx";`)

  // Remove from payload_locked_documents_rels
  await db.execute(sql`
    ALTER TABLE "payload_locked_documents_rels"
    DROP COLUMN IF EXISTS "report_schedules_id";
  `)

  // Drop tables
  await db.execute(sql`DROP TABLE IF EXISTS "report_schedules_rels";`)
  await db.execute(sql`DROP TABLE IF EXISTS "report_schedules_recipients";`)
  await db.execute(sql`DROP TABLE IF EXISTS "report_schedules";`)

  // Drop enums
  await db.execute(sql`DROP TYPE IF EXISTS "enum_report_schedules_format";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_report_schedules_timezone";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_report_schedules_report_type";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_report_schedules_day_of_week";`)
  await db.execute(sql`DROP TYPE IF EXISTS "enum_report_schedules_frequency";`)
}
