use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        let db = manager.get_connection();

        // User table: created_at, updated_at
        db.execute_unprepared(
            "ALTER TABLE \"user\" 
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP WITH TIME ZONE USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // Invite table: expires_at, revoked_at, created_at
        db.execute_unprepared(
            "ALTER TABLE invite 
             ALTER COLUMN expires_at TYPE TIMESTAMP WITH TIME ZONE USING expires_at AT TIME ZONE 'UTC',
             ALTER COLUMN revoked_at TYPE TIMESTAMP WITH TIME ZONE USING revoked_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC'"
        ).await?;

        // RecurrenceRule table: created_at, updated_at
        db.execute_unprepared(
            "ALTER TABLE recurrence_rule 
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP WITH TIME ZONE USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // Todo table: due_at, created_at, updated_at, check_in_at
        db.execute_unprepared(
            "ALTER TABLE todo 
             ALTER COLUMN due_at TYPE TIMESTAMP WITH TIME ZONE USING due_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP WITH TIME ZONE USING updated_at AT TIME ZONE 'UTC',
             ALTER COLUMN check_in_at TYPE TIMESTAMP WITH TIME ZONE USING check_in_at AT TIME ZONE 'UTC'"
        ).await?;

        // ReminderTask table: due_at, created_at, updated_at
        db.execute_unprepared(
            "ALTER TABLE reminder_task 
             ALTER COLUMN due_at TYPE TIMESTAMP WITH TIME ZONE USING due_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP WITH TIME ZONE USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // ReminderOffset table: created_at
        db.execute_unprepared(
            "ALTER TABLE reminder_offset 
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC'"
        ).await?;

        // Notification table: trigger_at, locked_at, sent_at, read_at, created_at, updated_at
        db.execute_unprepared(
            "ALTER TABLE notification 
             ALTER COLUMN trigger_at TYPE TIMESTAMP WITH TIME ZONE USING trigger_at AT TIME ZONE 'UTC',
             ALTER COLUMN locked_at TYPE TIMESTAMP WITH TIME ZONE USING locked_at AT TIME ZONE 'UTC',
             ALTER COLUMN sent_at TYPE TIMESTAMP WITH TIME ZONE USING sent_at AT TIME ZONE 'UTC',
             ALTER COLUMN read_at TYPE TIMESTAMP WITH TIME ZONE USING read_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP WITH TIME ZONE USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // DeliveryLog table: created_at
        db.execute_unprepared(
            "ALTER TABLE delivery_log 
             ALTER COLUMN created_at TYPE TIMESTAMP WITH TIME ZONE USING created_at AT TIME ZONE 'UTC'"
        ).await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        let db = manager.get_connection();

        // Revert User table
        db.execute_unprepared(
            "ALTER TABLE \"user\" 
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert Invite table
        db.execute_unprepared(
            "ALTER TABLE invite 
             ALTER COLUMN expires_at TYPE TIMESTAMP USING expires_at AT TIME ZONE 'UTC',
             ALTER COLUMN revoked_at TYPE TIMESTAMP USING revoked_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert RecurrenceRule table
        db.execute_unprepared(
            "ALTER TABLE recurrence_rule 
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert Todo table
        db.execute_unprepared(
            "ALTER TABLE todo 
             ALTER COLUMN due_at TYPE TIMESTAMP USING due_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC',
             ALTER COLUMN check_in_at TYPE TIMESTAMP USING check_in_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert ReminderTask table
        db.execute_unprepared(
            "ALTER TABLE reminder_task 
             ALTER COLUMN due_at TYPE TIMESTAMP USING due_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert ReminderOffset table
        db.execute_unprepared(
            "ALTER TABLE reminder_offset 
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert Notification table
        db.execute_unprepared(
            "ALTER TABLE notification 
             ALTER COLUMN trigger_at TYPE TIMESTAMP USING trigger_at AT TIME ZONE 'UTC',
             ALTER COLUMN locked_at TYPE TIMESTAMP USING locked_at AT TIME ZONE 'UTC',
             ALTER COLUMN sent_at TYPE TIMESTAMP USING sent_at AT TIME ZONE 'UTC',
             ALTER COLUMN read_at TYPE TIMESTAMP USING read_at AT TIME ZONE 'UTC',
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC',
             ALTER COLUMN updated_at TYPE TIMESTAMP USING updated_at AT TIME ZONE 'UTC'"
        ).await?;

        // Revert DeliveryLog table
        db.execute_unprepared(
            "ALTER TABLE delivery_log 
             ALTER COLUMN created_at TYPE TIMESTAMP USING created_at AT TIME ZONE 'UTC'"
        ).await?;

        Ok(())
    }
}
