SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
SET time_zone = '+00:00';

-- 单个带默认值的标记列在 MySQL 8 使用 INSTANT 元数据变更，不重写用户日宽表。
-- 生产执行前仍需确认 information_schema 与目标 MySQL 版本。
SET @add_profile_setup_view := (
  SELECT IF(
    COUNT(*) = 0,
    'ALTER TABLE stat_social_user_day ADD COLUMN profile_setup_view TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''填写资料页曝光去重标记'' AFTER app_first_open, ALGORITHM=INSTANT',
    'SELECT 1'
  )
  FROM information_schema.COLUMNS
  WHERE TABLE_SCHEMA = DATABASE()
    AND TABLE_NAME = 'stat_social_user_day'
    AND COLUMN_NAME = 'profile_setup_view'
);

PREPARE stmt FROM @add_profile_setup_view;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

-- profile_start 自 2026-07-09 客户端漏斗埋点上线后已经写入 statistics-service 原始事件表，
-- 但旧消费者尚未生成 Social 日投影。回灌固定从功能上线日开始，并同时生成 UTC/中国自然日两份；
-- FORCE INDEX 的等值 App+事件名和时间下界可使用 idx_app_tracking_event_window，避免全表扫描。
-- 同一主体日的多次曝光由主键和 GREATEST 收敛，迁移重复执行不会重复计数。
SET @profile_start_from_ms = UNIX_TIMESTAMP('2026-07-09 00:00:00') * 1000;
SET @profile_start_to_ms = UNIX_TIMESTAMP(UTC_TIMESTAMP(6)) * 1000;

INSERT INTO stat_social_user_day (
  app_code, stat_tz, stat_day, subject_key, user_id, device_id,
  country_id, region_id, user_role, profile_setup_view, updated_at_ms
)
SELECT
  event.app_code,
  timezone_scope.stat_tz,
  DATE(FROM_UNIXTIME((event.occurred_at_ms + timezone_scope.offset_ms) / 1000)),
  CASE
    WHEN event.user_id > 0 THEN CONCAT('u:', event.user_id)
    ELSE CONCAT('d:', event.device_id)
  END,
  event.user_id,
  event.device_id,
  event.country_id,
  event.region_id,
  'user',
  1,
  event.received_at_ms
FROM app_tracking_events event FORCE INDEX (idx_app_tracking_event_window)
CROSS JOIN (
  SELECT 'UTC' AS stat_tz, 0 AS offset_ms
  UNION ALL
  SELECT 'Asia/Shanghai' AS stat_tz, 28800000 AS offset_ms
) timezone_scope
WHERE event.app_code IN ('lalu', 'huwaa', 'fami')
  AND event.event_name = 'profile_start'
  AND event.occurred_at_ms >= @profile_start_from_ms
  AND event.occurred_at_ms < @profile_start_to_ms
ON DUPLICATE KEY UPDATE
  -- INSERT ... SELECT 的源表和目标表拥有同名列；目标旧值必须显式限定表名，
  -- 否则 MySQL 会把未限定列判定为 ambiguous，并留下只加列、未回灌的半迁移状态。
  user_id = CASE WHEN VALUES(user_id) > 0 THEN VALUES(user_id) ELSE stat_social_user_day.user_id END,
  device_id = CASE WHEN VALUES(device_id) <> '' THEN VALUES(device_id) ELSE stat_social_user_day.device_id END,
  country_id = CASE WHEN VALUES(country_id) > 0 THEN VALUES(country_id) ELSE stat_social_user_day.country_id END,
  region_id = CASE WHEN VALUES(region_id) > 0 THEN VALUES(region_id) ELSE stat_social_user_day.region_id END,
  profile_setup_view = GREATEST(stat_social_user_day.profile_setup_view, VALUES(profile_setup_view)),
  updated_at_ms = GREATEST(stat_social_user_day.updated_at_ms, VALUES(updated_at_ms));

SELECT ROW_COUNT() AS social_profile_setup_view_backfill_affected_rows;

SELECT
  COUNT(*) AS social_profile_setup_view_column_count
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'stat_social_user_day'
  AND COLUMN_NAME = 'profile_setup_view';
