-- Current MySQL schema for mini-program

-- Deprecated for shared deployments.
-- If `mini-program` and `talkingq-url` run on the same MySQL instance,
-- use `database/talkingq_shared_schema.sql` to initialize the single
-- source-of-truth database `talkingq`.
--
-- This file is kept only for legacy isolated development of mini-program.

CREATE DATABASE IF NOT EXISTS mini_program
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

USE mini_program;

-- parents
CREATE TABLE IF NOT EXISTS parents (
    user_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    openid VARCHAR(64) UNIQUE NOT NULL,
    unionid VARCHAR(64),
    nickname VARCHAR(64),
    avatar_url VARCHAR(255),
    avatar_file_key VARCHAR(255),
    phone VARCHAR(20),
    status TINYINT NOT NULL DEFAULT 1,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_parents_unionid ON parents(unionid);
CREATE INDEX idx_parents_phone ON parents(phone);

-- children
CREATE TABLE IF NOT EXISTS children (
    child_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    child_name VARCHAR(32) NOT NULL,
    child_gender TINYINT NOT NULL DEFAULT 2,
    child_birthday DATE,
    status TINYINT NOT NULL DEFAULT 1,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- parent_child_relations
CREATE TABLE IF NOT EXISTS parent_child_relations (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    child_id BIGINT NOT NULL,
    relation_type TINYINT NOT NULL DEFAULT 9,
    is_primary TINYINT(1) NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_user_child UNIQUE (user_id, child_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_pcr_user_id ON parent_child_relations(user_id);
CREATE INDEX idx_pcr_child_id ON parent_child_relations(child_id);

-- device_bindings
CREATE TABLE IF NOT EXISTS device_bindings (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    device_id VARCHAR(64) NOT NULL,
    owner_user_id BIGINT NOT NULL,
    child_id BIGINT,
    status TINYINT NOT NULL DEFAULT 1,
    bound_at DATETIME NOT NULL,
    unbound_at DATETIME,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_device_binding_device UNIQUE (device_id),
    CONSTRAINT uq_device_binding_child UNIQUE (child_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_device_bindings_owner_user_id ON device_bindings(owner_user_id);

-- device_bind_sessions
CREATE TABLE IF NOT EXISTS device_bind_sessions (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    bind_token CHAR(36) UNIQUE NOT NULL,
    device_id VARCHAR(64) NOT NULL,
    initiator_user_id BIGINT NOT NULL,
    target_child_id BIGINT,
    challenge_code_hash CHAR(64),
    challenge_set_at DATETIME,
    expires_at DATETIME NOT NULL,
    max_attempt_count TINYINT UNSIGNED NOT NULL DEFAULT 5,
    attempt_count TINYINT UNSIGNED NOT NULL DEFAULT 0,
    status TINYINT NOT NULL DEFAULT 1,
    confirmed_at DATETIME,
    consumed_at DATETIME,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- device_bind_history
CREATE TABLE IF NOT EXISTS device_bind_history (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    device_id VARCHAR(64) NOT NULL,
    child_id BIGINT,
    bound_by_user_id BIGINT NOT NULL,
    unbound_by_user_id BIGINT,
    bind_source TINYINT NOT NULL DEFAULT 1,
    bound_at DATETIME NOT NULL,
    unbound_at DATETIME,
    unbind_reason VARCHAR(191),
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- cards
CREATE TABLE IF NOT EXISTS cards (
    card_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    card_uuid VARCHAR(64) UNIQUE NOT NULL,
    device_id VARCHAR(64) UNIQUE,
    card_name VARCHAR(64),
    status TINYINT NOT NULL DEFAULT 0,
    total_swaps INT NOT NULL DEFAULT 0,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- device_settings
CREATE TABLE IF NOT EXISTS device_settings (
    setting_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    device_id VARCHAR(64) NOT NULL UNIQUE,
    sleep_mode TINYINT NOT NULL DEFAULT 0,
    disable_time_start TIME,
    disable_time_end TIME,
    timezone VARCHAR(32) NOT NULL DEFAULT 'Asia/Shanghai',
    volume TINYINT UNSIGNED,
    brightness TINYINT UNSIGNED,
    disable_weekdays VARCHAR(32),
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- im_conversations
CREATE TABLE IF NOT EXISTS im_conversations (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    conversation_type TINYINT UNSIGNED NOT NULL,
    participant_a_type TINYINT UNSIGNED NOT NULL,
    participant_a_id VARCHAR(64) NOT NULL,
    participant_b_type TINYINT UNSIGNED NOT NULL,
    participant_b_id VARCHAR(64) NOT NULL,
    pair_key VARCHAR(191) NOT NULL,
    status TINYINT NOT NULL DEFAULT 1,
    last_seq BIGINT UNSIGNED NOT NULL DEFAULT 0,
    message_count BIGINT UNSIGNED NOT NULL DEFAULT 0,
    last_message_preview VARCHAR(255),
    last_message_at DATETIME,
    ext_json JSON,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_conv_type_pair UNIQUE (conversation_type, pair_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_im_conv_participant_a ON im_conversations(participant_a_type, participant_a_id);
CREATE INDEX idx_im_conv_participant_b ON im_conversations(participant_b_type, participant_b_id);
CREATE INDEX idx_im_conv_last_message_at ON im_conversations(last_message_at);

-- im_messages
CREATE TABLE IF NOT EXISTS im_messages (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    conversation_id BIGINT UNSIGNED NOT NULL,
    seq BIGINT UNSIGNED NOT NULL,
    sender_type TINYINT UNSIGNED NOT NULL,
    sender_id VARCHAR(64) NOT NULL,
    receiver_type TINYINT UNSIGNED NOT NULL,
    receiver_id VARCHAR(64) NOT NULL,
    content_type TINYINT UNSIGNED NOT NULL,
    content_text MEDIUMTEXT,
    content_json JSON,
    media_file_key VARCHAR(255),
    media_duration_ms INT UNSIGNED,
    media_mime_type VARCHAR(64),
    media_size_bytes BIGINT UNSIGNED,
    media_transcript_text TEXT,
    client_msg_id VARCHAR(64),
    sender_name_snapshot VARCHAR(64),
    sender_avatar_snapshot VARCHAR(255),
    receiver_name_snapshot VARCHAR(64),
    receiver_avatar_snapshot VARCHAR(255),
    ext_json JSON,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at DATETIME,
    CONSTRAINT uq_im_msg_conv_seq UNIQUE (conversation_id, seq),
    CONSTRAINT uq_im_msg_client UNIQUE (conversation_id, client_msg_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_im_msg_sender ON im_messages(sender_type, sender_id, created_at);
CREATE INDEX idx_im_msg_receiver ON im_messages(receiver_type, receiver_id, created_at);

-- device_pending_voice_messages
CREATE TABLE IF NOT EXISTS device_pending_voice_messages (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    target_device_id VARCHAR(64) NOT NULL,
    sender_device_id VARCHAR(64),
    im_message_id BIGINT NOT NULL,
    media_file_key VARCHAR(255) NOT NULL,
    audio_url VARCHAR(512),
    source VARCHAR(32) NOT NULL DEFAULT 'unknown',
    status VARCHAR(32) NOT NULL DEFAULT 'pending',
    delivery_count INT NOT NULL DEFAULT 0,
    delivered_at DATETIME,
    listened_at DATETIME,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT uq_device_pending_voice_target_msg UNIQUE (target_device_id, im_message_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_device_pending_voice_target_status_created ON device_pending_voice_messages(target_device_id, status, created_at);
CREATE INDEX idx_device_pending_voice_sender ON device_pending_voice_messages(sender_device_id);
CREATE INDEX idx_device_pending_voice_im_message ON device_pending_voice_messages(im_message_id);

-- child_location_current
CREATE TABLE IF NOT EXISTS child_location_current (
    child_id BIGINT UNSIGNED PRIMARY KEY,
    device_id VARCHAR(64) NOT NULL,
    coord_type VARCHAR(16) NOT NULL DEFAULT 'gcj02',
    lat DECIMAL(10,7) NOT NULL,
    lng DECIMAL(10,7) NOT NULL,
    accuracy_m INT UNSIGNED,
    altitude_m DECIMAL(8,2),
    speed_mps DECIMAL(8,2),
    heading_deg SMALLINT UNSIGNED,
    source TINYINT UNSIGNED NOT NULL,
    battery_pct TINYINT UNSIGNED,
    device_time DATETIME NOT NULL,
    server_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- child_location_history
CREATE TABLE IF NOT EXISTS child_location_history (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    child_id BIGINT UNSIGNED NOT NULL,
    device_id VARCHAR(64) NOT NULL,
    coord_type VARCHAR(16) NOT NULL DEFAULT 'gcj02',
    lat DECIMAL(10,7) NOT NULL,
    lng DECIMAL(10,7) NOT NULL,
    accuracy_m INT UNSIGNED,
    altitude_m DECIMAL(8,2),
    speed_mps DECIMAL(8,2),
    heading_deg SMALLINT UNSIGNED,
    source TINYINT UNSIGNED NOT NULL,
    battery_pct TINYINT UNSIGNED,
    device_time DATETIME NOT NULL,
    server_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE INDEX idx_child_loc_hist_child ON child_location_history(child_id, created_at);
