package mysql

import "context"

// ensureTemporaryGrowthLevelTables keeps auto-migrated local/test databases compatible with the deploy migration.
// Production rollout still applies the explicit SQL before starting new binaries.
func (r *Repository) ensureTemporaryGrowthLevelTables(ctx context.Context) error {
	additions := []struct {
		column string
		sql    string
	}{
		{"reward_origin", `ALTER TABLE growth_level_reward_jobs ADD COLUMN reward_origin VARCHAR(32) NOT NULL DEFAULT 'organic' AFTER wallet_grant_id`},
		{"temporary_level_id", `ALTER TABLE growth_level_reward_jobs ADD COLUMN temporary_level_id VARCHAR(96) NOT NULL DEFAULT '' AFTER reward_origin`},
		{"grant_generation", `ALTER TABLE growth_level_reward_jobs ADD COLUMN grant_generation INT NOT NULL DEFAULT 0 AFTER temporary_level_id`},
		{"reward_level", `ALTER TABLE growth_level_reward_jobs ADD COLUMN reward_level INT NOT NULL DEFAULT 0 AFTER grant_generation`},
		{"is_permanent", `ALTER TABLE growth_level_reward_jobs ADD COLUMN is_permanent TINYINT(1) NOT NULL DEFAULT 1 AFTER reward_level`},
		{"temporary_expires_at_ms", `ALTER TABLE growth_level_reward_jobs ADD COLUMN temporary_expires_at_ms BIGINT NOT NULL DEFAULT 0 AFTER is_permanent`},
		{"revoke_status", `ALTER TABLE growth_level_reward_jobs ADD COLUMN revoke_status VARCHAR(32) NOT NULL DEFAULT 'none' AFTER temporary_expires_at_ms`},
	}
	for _, addition := range additions {
		exists, err := r.columnExists(ctx, "growth_level_reward_jobs", addition.column)
		if err != nil {
			return err
		}
		if !exists {
			if _, err := r.db.ExecContext(ctx, addition.sql); err != nil {
				return err
			}
		}
	}
	oldIndex, err := r.indexExists(ctx, "growth_level_reward_jobs", "uk_growth_level_reward_once")
	if err != nil {
		return err
	}
	newIndex, err := r.indexExists(ctx, "growth_level_reward_jobs", "uk_growth_level_reward_generation")
	if err != nil {
		return err
	}
	if oldIndex {
		if _, err := r.db.ExecContext(ctx, `ALTER TABLE growth_level_reward_jobs DROP INDEX uk_growth_level_reward_once`); err != nil {
			return err
		}
	}
	if !newIndex {
		if _, err := r.db.ExecContext(ctx, `CREATE UNIQUE INDEX uk_growth_level_reward_generation ON growth_level_reward_jobs (app_code, user_id, track, reward_source_type, reward_source_id, reward_origin, grant_generation)`); err != nil {
			return err
		}
	}
	statements := []string{
		`CREATE TABLE IF NOT EXISTS growth_level_reward_wallet_grants (
		  app_code VARCHAR(32) NOT NULL DEFAULT 'lalu', reward_job_id VARCHAR(96) NOT NULL,
		  grant_kind VARCHAR(32) NOT NULL, wallet_grant_id VARCHAR(96) NOT NULL,
		  revoke_status VARCHAR(32) NOT NULL DEFAULT 'none', revoke_attempt_count INT NOT NULL DEFAULT 0,
		  revoke_next_retry_at_ms BIGINT NOT NULL DEFAULT 0, revoke_locked_by VARCHAR(128) NOT NULL DEFAULT '',
		  revoke_locked_until_ms BIGINT NOT NULL DEFAULT 0, revoke_failure_reason VARCHAR(255) NOT NULL DEFAULT '',
		  revoked_at_ms BIGINT NOT NULL DEFAULT 0, created_at_ms BIGINT NOT NULL, updated_at_ms BIGINT NOT NULL,
		  PRIMARY KEY (app_code, reward_job_id, wallet_grant_id),
		  KEY idx_growth_reward_grant_revoke (app_code, revoke_status, revoke_next_retry_at_ms, created_at_ms)
		) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
		`CREATE TABLE IF NOT EXISTS growth_temporary_level_commands (
		  app_code VARCHAR(32) NOT NULL DEFAULT 'lalu', command_id VARCHAR(128) NOT NULL,
		  request_hash VARCHAR(64) NOT NULL, user_id BIGINT NOT NULL, operator_admin_id BIGINT NOT NULL,
		  created_at_ms BIGINT NOT NULL, PRIMARY KEY (app_code, command_id)
		) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
		`CREATE TABLE IF NOT EXISTS growth_temporary_levels (
		  app_code VARCHAR(32) NOT NULL DEFAULT 'lalu', temporary_level_id VARCHAR(96) NOT NULL,
		  command_id VARCHAR(128) NOT NULL, user_id BIGINT NOT NULL, track VARCHAR(32) NOT NULL,
		  target_level INT NOT NULL, target_required_value BIGINT NOT NULL, baseline_total_value BIGINT NOT NULL,
		  started_at_ms BIGINT NOT NULL, expires_at_ms BIGINT NOT NULL, status VARCHAR(32) NOT NULL,
		  generation INT NOT NULL, operator_admin_id BIGINT NOT NULL, reason VARCHAR(255) NOT NULL DEFAULT '',
		  final_level INT NOT NULL DEFAULT 0, activation_notice_status VARCHAR(32) NOT NULL DEFAULT 'pending',
		  expiry_notice_status VARCHAR(32) NOT NULL DEFAULT 'skipped', attempt_count INT NOT NULL DEFAULT 0,
		  next_retry_at_ms BIGINT NOT NULL DEFAULT 0, locked_by VARCHAR(128) NOT NULL DEFAULT '',
		  locked_until_ms BIGINT NOT NULL DEFAULT 0, failure_reason VARCHAR(255) NOT NULL DEFAULT '',
		  created_at_ms BIGINT NOT NULL, updated_at_ms BIGINT NOT NULL,
		  PRIMARY KEY (app_code, temporary_level_id),
		  UNIQUE KEY uk_growth_temp_command_track (app_code, command_id, track),
		  KEY idx_growth_temp_user_track (app_code, user_id, track, status, expires_at_ms),
		  KEY idx_growth_temp_work (app_code, status, next_retry_at_ms, expires_at_ms, created_at_ms)
		) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`,
	}
	for _, statement := range statements {
		if _, err := r.db.ExecContext(ctx, statement); err != nil {
			return err
		}
	}
	return nil
}
