CREATE TABLE `challenge_session_answers` (
	`id` char(36) NOT NULL,
	`session_id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`question_id` char(36) NOT NULL,
	`submit_request_id` varchar(80) NOT NULL,
	`answer_order` tinyint NOT NULL,
	`answer` varchar(500),
	`correct` tinyint NOT NULL,
	`time_ms` int,
	`combo_count` tinyint DEFAULT 0,
	`result_snapshot` json,
	`submitted_at` datetime DEFAULT CURRENT_TIMESTAMP,
	CONSTRAINT `challenge_session_answers_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_challenge_answer_session_question` UNIQUE(`session_id`,`question_id`),
	CONSTRAINT `uk_challenge_answer_session_request` UNIQUE(`session_id`,`submit_request_id`)
);
--> statement-breakpoint
CREATE TABLE `challenge_sessions` (
	`id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`track_id` varchar(50) NOT NULL,
	`category_id` varchar(50) NOT NULL,
	`chapter_id` char(36),
	`status` enum('pending','in_progress','completed','abandoned','expired') DEFAULT 'pending',
	`client_request_id` varchar(80) NOT NULL,
	`complete_request_id` varchar(80),
	`question_ids` json NOT NULL,
	`total_questions` tinyint DEFAULT 5,
	`answered_count` tinyint DEFAULT 0,
	`correct_count` tinyint DEFAULT 0,
	`high_reward_eligible` tinyint DEFAULT 1,
	`reward_snapshot` json,
	`progress_before` json,
	`progress_after` json,
	`expires_at` datetime,
	`completed_at` datetime,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `challenge_sessions_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_challenge_session_user_client_request` UNIQUE(`user_id`,`client_request_id`),
	CONSTRAINT `uk_challenge_session_user_complete_request` UNIQUE(`user_id`,`complete_request_id`)
);
--> statement-breakpoint
CREATE TABLE `inventory_transactions` (
	`id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`inventory_item_id` char(36),
	`item_id` enum('coins','streak_shield','double_xp_potion','heart_supply','hint_feather','mascot_outfit') NOT NULL,
	`direction` enum('grant','consume','adjust') NOT NULL,
	`quantity_delta` int NOT NULL,
	`balance_after` int,
	`source_type` enum('challenge','daily_task','level_up','theme_node','chest','shop_purchase','ad_recovery','subscription','admin_grant','system_adjust') NOT NULL,
	`source_id` varchar(120),
	`idempotency_key` varchar(160),
	`snapshot` json,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	CONSTRAINT `inventory_transactions_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_inventory_transaction_idempotency` UNIQUE(`user_id`,`idempotency_key`)
);
--> statement-breakpoint
CREATE TABLE `reward_ledger` (
	`id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`source_type` enum('challenge_answer','challenge_completion','daily_task','streak_milestone','level_up','theme_node','knowledge_card','chest','shop_purchase','ad_recovery','leaderboard_settlement','subscription','admin_grant','system_adjust') NOT NULL,
	`source_id` varchar(120),
	`idempotency_key` varchar(160) NOT NULL,
	`status` enum('pending','settling','completed','failed','reversed') DEFAULT 'pending',
	`reward_snapshot` json NOT NULL,
	`resource_deltas` json,
	`state_before` json,
	`state_after` json,
	`failure_reason` varchar(120),
	`settled_at` datetime,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `reward_ledger_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_reward_ledger_user_idempotency` UNIQUE(`user_id`,`idempotency_key`)
);
--> statement-breakpoint
CREATE TABLE `user_daily_progress` (
	`id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`progress_date` date NOT NULL,
	`timezone` varchar(50) DEFAULT 'UTC',
	`first_challenge_session_id` char(36),
	`first_challenge_completed_at` datetime,
	`challenge_sessions_completed` smallint DEFAULT 0,
	`high_reward_sessions_max` smallint DEFAULT 3,
	`high_reward_sessions_used` smallint DEFAULT 0,
	`high_reward_sessions_restored` smallint DEFAULT 0,
	`daily_tasks_completed` smallint DEFAULT 0,
	`daily_tasks_reward_claimed` smallint DEFAULT 0,
	`xp_earned` int DEFAULT 0,
	`coins_earned` int DEFAULT 0,
	`streak_counted` tinyint DEFAULT 0,
	`metadata` json,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `user_daily_progress_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_daily_progress_user_date` UNIQUE(`user_id`,`progress_date`)
);
--> statement-breakpoint
CREATE TABLE `user_daily_tasks` (
	`id` char(36) NOT NULL,
	`daily_progress_id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`task_date` date NOT NULL,
	`task_id` varchar(80) NOT NULL,
	`task_type` enum('complete_challenge','earn_xp','answer_correct','review_explanation','use_item','watch_ad') NOT NULL,
	`target_count` smallint DEFAULT 1,
	`current_count` smallint DEFAULT 0,
	`status` enum('active','completed','reward_claimed','expired') DEFAULT 'active',
	`reward_snapshot` json,
	`completed_at` datetime,
	`reward_claimed_at` datetime,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `user_daily_tasks_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_daily_task_user_date_task` UNIQUE(`user_id`,`task_date`,`task_id`)
);
--> statement-breakpoint
CREATE TABLE `user_inventory_items` (
	`id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`item_id` enum('streak_shield','double_xp_potion','heart_supply','hint_feather','mascot_outfit') NOT NULL,
	`quantity` int DEFAULT 0,
	`active_until` datetime,
	`metadata` json,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `user_inventory_items_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_inventory_user_item` UNIQUE(`user_id`,`item_id`)
);
--> statement-breakpoint
CREATE TABLE `user_wallets` (
	`user_id` char(36) NOT NULL,
	`coins_balance` int DEFAULT 0,
	`lifetime_coins_earned` int DEFAULT 0,
	`lifetime_coins_spent` int DEFAULT 0,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `user_wallets_user_id` PRIMARY KEY(`user_id`)
);
--> statement-breakpoint
CREATE TABLE `user_weekly_xp` (
	`id` char(36) NOT NULL,
	`user_id` char(36) NOT NULL,
	`week_start` date NOT NULL,
	`week_end` date NOT NULL,
	`timezone` varchar(50) DEFAULT 'UTC',
	`xp_earned` int DEFAULT 0,
	`challenge_sessions_completed` int DEFAULT 0,
	`group_id` varchar(80),
	`rank` int,
	`settled` tinyint DEFAULT 0,
	`settled_at` datetime,
	`last_xp_at` datetime,
	`next_refresh_at` datetime,
	`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
	`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	CONSTRAINT `user_weekly_xp_id` PRIMARY KEY(`id`),
	CONSTRAINT `uk_weekly_xp_user_week` UNIQUE(`user_id`,`week_start`)
);
--> statement-breakpoint
DROP INDEX `idx_user_week` ON `leaderboard_snapshots`;--> statement-breakpoint
ALTER TABLE `leaderboard_snapshots` MODIFY COLUMN `week_start` date NOT NULL;--> statement-breakpoint
ALTER TABLE `leaderboard_snapshots` MODIFY COLUMN `week_end` date NOT NULL;--> statement-breakpoint
ALTER TABLE `leaderboard_snapshots` ADD `group_id` varchar(80);--> statement-breakpoint
ALTER TABLE `leaderboard_snapshots` ADD `reward_snapshot` json;--> statement-breakpoint
ALTER TABLE `leaderboard_snapshots` ADD `settled_at` datetime;--> statement-breakpoint
ALTER TABLE `leaderboard_snapshots` ADD CONSTRAINT `uk_leaderboard_snapshot_user_week` UNIQUE(`user_id`,`week_start`);--> statement-breakpoint
ALTER TABLE `challenge_session_answers` ADD CONSTRAINT `challenge_session_answers_session_id_challenge_sessions_id_fk` FOREIGN KEY (`session_id`) REFERENCES `challenge_sessions`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `challenge_session_answers` ADD CONSTRAINT `challenge_session_answers_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `challenge_session_answers` ADD CONSTRAINT `challenge_session_answers_question_id_questions_id_fk` FOREIGN KEY (`question_id`) REFERENCES `questions`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `challenge_sessions` ADD CONSTRAINT `challenge_sessions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `challenge_sessions` ADD CONSTRAINT `challenge_sessions_category_id_categories_id_fk` FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `challenge_sessions` ADD CONSTRAINT `challenge_sessions_chapter_id_skill_tree_id_fk` FOREIGN KEY (`chapter_id`) REFERENCES `skill_tree`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `inventory_transactions` ADD CONSTRAINT `inventory_transactions_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `inventory_transactions` ADD CONSTRAINT `inventory_transactions_inventory_item_id_user_inventory_items_id_fk` FOREIGN KEY (`inventory_item_id`) REFERENCES `user_inventory_items`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `reward_ledger` ADD CONSTRAINT `reward_ledger_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_daily_progress` ADD CONSTRAINT `user_daily_progress_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_daily_progress` ADD CONSTRAINT `user_daily_progress_first_challenge_session_id_challenge_sessions_id_fk` FOREIGN KEY (`first_challenge_session_id`) REFERENCES `challenge_sessions`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_daily_tasks` ADD CONSTRAINT `user_daily_tasks_daily_progress_id_user_daily_progress_id_fk` FOREIGN KEY (`daily_progress_id`) REFERENCES `user_daily_progress`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_daily_tasks` ADD CONSTRAINT `user_daily_tasks_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_inventory_items` ADD CONSTRAINT `user_inventory_items_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_wallets` ADD CONSTRAINT `user_wallets_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE `user_weekly_xp` ADD CONSTRAINT `user_weekly_xp_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE no action ON UPDATE no action;--> statement-breakpoint
CREATE INDEX `idx_challenge_answer_user_submitted` ON `challenge_session_answers` (`user_id`,`submitted_at`);--> statement-breakpoint
CREATE INDEX `idx_challenge_session_user_status_created` ON `challenge_sessions` (`user_id`,`status`,`created_at`);--> statement-breakpoint
CREATE INDEX `idx_challenge_session_chapter_status` ON `challenge_sessions` (`chapter_id`,`status`);--> statement-breakpoint
CREATE INDEX `idx_inventory_transaction_user_created` ON `inventory_transactions` (`user_id`,`created_at`);--> statement-breakpoint
CREATE INDEX `idx_inventory_transaction_source` ON `inventory_transactions` (`source_type`,`source_id`);--> statement-breakpoint
CREATE INDEX `idx_reward_ledger_user_status_created` ON `reward_ledger` (`user_id`,`status`,`created_at`);--> statement-breakpoint
CREATE INDEX `idx_reward_ledger_source` ON `reward_ledger` (`source_type`,`source_id`);--> statement-breakpoint
CREATE INDEX `idx_daily_progress_date` ON `user_daily_progress` (`progress_date`);--> statement-breakpoint
CREATE INDEX `idx_daily_task_progress_status` ON `user_daily_tasks` (`daily_progress_id`,`status`);--> statement-breakpoint
CREATE INDEX `idx_inventory_user_active` ON `user_inventory_items` (`user_id`,`active_until`);--> statement-breakpoint
CREATE INDEX `idx_weekly_xp_group_rank` ON `user_weekly_xp` (`group_id`,`week_start`,`xp_earned`);--> statement-breakpoint
CREATE INDEX `idx_weekly_xp_week_settled` ON `user_weekly_xp` (`week_start`,`settled`);--> statement-breakpoint
CREATE INDEX `idx_leaderboard_snapshot_group_rank` ON `leaderboard_snapshots` (`group_id`,`week_start`,`rank`);