-- Yumi Gift Challenge: ordinary GOLD gift ledger, daily/overall ranking, three daily tasks,
-- frozen reward templates and two-phase item-level settlement.
--
-- Performance review:
-- 1. The MQ hot path resolves at most one enabled activity through
--    (sys_origin, enabled, start_time, end_time), deduplicates by a unique event key, and updates
--    one overall plus one daily aggregate primary key. Ranking never GROUP BYs the gift ledger.
-- 2. Daily/overall ranks use covering order indexes matching
--    score DESC, score_reached_time ASC, user_id ASC; user-rank counts remain activity/date scoped.
-- 3. Settlement discovery uses (status, snapshot_due_time), while parent and delivery claims use
--    unique owner/business keys and narrow owner/status indexes. UNKNOWN items are never auto-retried.
-- 4. This migration creates empty tables only: no UPDATE, DELETE, backfill, table-copy ALTER, or
--    unbounded scan is executed. Run DDL under the target database's normal online-DDL policy.

SET NAMES utf8mb4;

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_activity` (
  `id` BIGINT NOT NULL,
  `activity_code` VARCHAR(64) NOT NULL,
  `activity_name` VARCHAR(128) NOT NULL,
  `activity_desc` VARCHAR(1000) NOT NULL DEFAULT '',
  `sys_origin` VARCHAR(32) NOT NULL,
  `time_zone` VARCHAR(64) NOT NULL DEFAULT 'Asia/Riyadh',
  `start_time` DATETIME(3) NOT NULL,
  `end_time` DATETIME(3) NOT NULL,
  `daily_settlement_delay_minutes` INT NOT NULL DEFAULT 30,
  `overall_settlement_delay_minutes` INT NOT NULL DEFAULT 30,
  `overall_settlement_time` DATETIME(3) NOT NULL,
  `display_top_n` INT NOT NULL DEFAULT 100,
  `enabled` TINYINT(1) NOT NULL DEFAULT 0,
  `overall_settlement_status` VARCHAR(32) NOT NULL DEFAULT 'NOT_STARTED',
  `version` INT NOT NULL DEFAULT 0,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_activity_code` (`activity_code`),
  KEY `idx_yumi_gc_activity_window` (`sys_origin`, `enabled`, `start_time`, `end_time`),
  KEY `idx_yumi_gc_activity_settle` (`overall_settlement_status`, `overall_settlement_time`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Yumi gift challenge activity cycle';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_task_config` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `task_code` VARCHAR(64) NOT NULL,
  `task_type` VARCHAR(32) NOT NULL,
  `task_title` VARCHAR(128) NOT NULL,
  `task_desc` VARCHAR(500) NOT NULL DEFAULT '',
  `target_value` DECIMAL(24,2) NOT NULL,
  `resource_group_id` BIGINT NULL,
  `enabled` TINYINT(1) NOT NULL DEFAULT 1,
  `sort_order` TINYINT NOT NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_task_code` (`activity_id`, `task_code`),
  UNIQUE KEY `uk_yumi_gc_task_sort` (`activity_id`, `sort_order`),
  KEY `idx_yumi_gc_task_enabled` (`activity_id`, `enabled`, `sort_order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Exactly three Yumi gift challenge daily tasks';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_rank_reward` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `period_type` VARCHAR(16) NOT NULL,
  `start_rank` INT NOT NULL,
  `end_rank` INT NOT NULL,
  `resource_group_id` BIGINT NOT NULL,
  `reward_name` VARCHAR(128) NOT NULL DEFAULT '',
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_rank_range` (`activity_id`, `period_type`, `start_rank`, `end_rank`),
  KEY `idx_yumi_gc_rank_match` (`activity_id`, `period_type`, `start_rank`, `end_rank`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Configurable daily and overall rank reward ranges';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_reward_snapshot` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `resource_group_id` BIGINT NOT NULL,
  `reward_config_id` BIGINT NOT NULL,
  `reward_type` VARCHAR(64) NOT NULL,
  `detail_type` VARCHAR(64) NOT NULL DEFAULT '',
  `content` TEXT NOT NULL,
  `quantity` BIGINT NOT NULL,
  `sort_order` INT NOT NULL DEFAULT 0,
  `remark` VARCHAR(500) NOT NULL DEFAULT '',
  `cover` TEXT NOT NULL,
  `source_url` TEXT NOT NULL,
  `display_name` VARCHAR(500) NOT NULL DEFAULT '',
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_snapshot_item` (`activity_id`, `resource_group_id`, `reward_config_id`),
  KEY `idx_yumi_gc_snapshot_group` (`activity_id`, `resource_group_id`, `sort_order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Full reward item template frozen when activity is enabled';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_gift_ledger` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `source_event_track_id` VARCHAR(128) NOT NULL,
  `user_id` BIGINT NOT NULL,
  `gift_id` BIGINT NOT NULL,
  `gift_tab` VARCHAR(32) NOT NULL,
  `amount` DECIMAL(24,2) NOT NULL,
  `event_time` DATETIME(3) NOT NULL,
  `stat_date` DATE NOT NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_ledger_event` (`activity_id`, `source_event_track_id`),
  KEY `idx_yumi_gc_ledger_user` (`activity_id`, `user_id`, `event_time`),
  KEY `idx_yumi_gc_ledger_date` (`activity_id`, `stat_date`, `event_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Idempotent ordinary GOLD gift activity ledger';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_user_score` (
  `activity_id` BIGINT NOT NULL,
  `user_id` BIGINT NOT NULL,
  `score` DECIMAL(24,2) NOT NULL DEFAULT 0.00,
  `score_reached_time` DATETIME(3) NOT NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`activity_id`, `user_id`),
  KEY `idx_yumi_gc_overall_rank` (`activity_id`, `score` DESC, `score_reached_time` ASC, `user_id` ASC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Materialized overall gift challenge score';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_user_daily_score` (
  `activity_id` BIGINT NOT NULL,
  `stat_date` DATE NOT NULL,
  `user_id` BIGINT NOT NULL,
  `score` DECIMAL(24,2) NOT NULL DEFAULT 0.00,
  `score_reached_time` DATETIME(3) NOT NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`activity_id`, `stat_date`, `user_id`),
  KEY `idx_yumi_gc_daily_rank` (`activity_id`, `stat_date`, `score` DESC, `score_reached_time` ASC, `user_id` ASC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Materialized activity-timezone daily gift challenge score';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_user_task_daily` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `stat_date` DATE NOT NULL,
  `user_id` BIGINT NOT NULL,
  `task_config_id` BIGINT NOT NULL,
  `task_code` VARCHAR(64) NOT NULL,
  `task_type` VARCHAR(32) NOT NULL,
  `task_title` VARCHAR(128) NOT NULL,
  `sort_order` TINYINT NOT NULL,
  `target_value` DECIMAL(24,2) NOT NULL,
  `progress_value` DECIMAL(24,2) NOT NULL DEFAULT 0.00,
  `completed_time` DATETIME(3) NULL,
  `resource_group_id` BIGINT NULL,
  `business_no` VARCHAR(160) NOT NULL,
  `claim_request_id` VARCHAR(128) NOT NULL DEFAULT '',
  `delivery_status` VARCHAR(32) NOT NULL DEFAULT 'NOT_CLAIMED',
  `retry_count` INT NOT NULL DEFAULT 0,
  `failure_reason` VARCHAR(500) NOT NULL DEFAULT '',
  `claimed_time` DATETIME(3) NULL,
  `deliver_time` DATETIME(3) NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_user_task` (`activity_id`, `stat_date`, `user_id`, `task_code`),
  UNIQUE KEY `uk_yumi_gc_task_business` (`business_no`),
  KEY `idx_yumi_gc_user_task_page` (`activity_id`, `stat_date`, `user_id`, `sort_order`),
  KEY `idx_yumi_gc_task_delivery` (`delivery_status`, `update_time`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Frozen per-user per-day task state and reward owner';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_period_settlement` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `period_type` VARCHAR(16) NOT NULL,
  `period_key` VARCHAR(16) NOT NULL,
  `stat_date` DATE NULL,
  `snapshot_due_time` DATETIME(3) NOT NULL,
  `status` VARCHAR(32) NOT NULL DEFAULT 'NOT_STARTED',
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_period` (`activity_id`, `period_type`, `period_key`),
  KEY `idx_yumi_gc_period_due` (`status`, `snapshot_due_time`, `id`),
  KEY `idx_yumi_gc_period_activity` (`activity_id`, `status`, `period_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Daily and overall write gates including empty periods';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_settlement` (
  `id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `period_type` VARCHAR(16) NOT NULL,
  `period_key` VARCHAR(16) NOT NULL,
  `stat_date` DATE NULL,
  `user_id` BIGINT NOT NULL,
  `rank_no` INT NOT NULL,
  `score` DECIMAL(24,2) NOT NULL,
  `rank_reward_id` BIGINT NOT NULL,
  `resource_group_id` BIGINT NOT NULL,
  `business_no` VARCHAR(180) NOT NULL,
  `delivery_status` VARCHAR(32) NOT NULL DEFAULT 'PENDING',
  `retry_count` INT NOT NULL DEFAULT 0,
  `failure_reason` VARCHAR(500) NOT NULL DEFAULT '',
  `deliver_time` DATETIME(3) NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_settle_user` (`activity_id`, `period_type`, `period_key`, `user_id`),
  UNIQUE KEY `uk_yumi_gc_settle_rank` (`activity_id`, `period_type`, `period_key`, `rank_no`),
  UNIQUE KEY `uk_yumi_gc_settle_business` (`business_no`),
  KEY `idx_yumi_gc_settle_status` (`activity_id`, `period_type`, `period_key`, `delivery_status`, `rank_no`),
  KEY `idx_yumi_gc_settle_recovery` (`delivery_status`, `update_time`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Frozen rank winner parent records';

CREATE TABLE IF NOT EXISTS `yumi_gift_challenge_delivery_item` (
  `id` BIGINT NOT NULL,
  `owner_type` VARCHAR(16) NOT NULL COMMENT 'TASK or SETTLEMENT',
  `owner_id` BIGINT NOT NULL,
  `activity_id` BIGINT NOT NULL,
  `user_id` BIGINT NOT NULL,
  `reward_config_id` BIGINT NOT NULL,
  `resource_group_id` BIGINT NOT NULL,
  `reward_type` VARCHAR(64) NOT NULL,
  `detail_type` VARCHAR(64) NOT NULL DEFAULT '',
  `content` TEXT NOT NULL,
  `quantity` BIGINT NOT NULL,
  `sort_order` INT NOT NULL DEFAULT 0,
  `remark` VARCHAR(500) NOT NULL DEFAULT '',
  `delivery_status` VARCHAR(32) NOT NULL DEFAULT 'PENDING',
  `retry_count` INT NOT NULL DEFAULT 0,
  `failure_reason` VARCHAR(500) NOT NULL DEFAULT '',
  `deliver_time` DATETIME(3) NULL,
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_yumi_gc_delivery_item` (`owner_type`, `owner_id`, `reward_config_id`),
  KEY `idx_yumi_gc_delivery_claim` (`owner_type`, `owner_id`, `delivery_status`, `sort_order`, `id`),
  KEY `idx_yumi_gc_delivery_stale` (`delivery_status`, `update_time`, `id`),
  KEY `idx_yumi_gc_delivery_activity` (`activity_id`, `delivery_status`, `id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Item-level idempotent frozen reward delivery';
