CREATE TABLE users (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    username text NOT NULL UNIQUE,
    email text NOT NULL UNIQUE,
    password_hash text NOT NULL,
    full_name text,
    role text NOT NULL DEFAULT 'user',
    active boolean NOT NULL DEFAULT true,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE rooms (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    name text NOT NULL,
    code text,
    location text,
    description text,
    capacity bigint,
    stage varchar(32),
    region varchar(64),
    status text NOT NULL DEFAULT 'active',
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE devices (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    device_key text NOT NULL UNIQUE,
    name text NOT NULL,
    kind text NOT NULL DEFAULT 'sensor',
    model text,
    firmware text,
    online_status text NOT NULL DEFAULT 'online',
    last_seen timestamptz,
    room_id uuid NOT NULL,
    topic text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_devices_room_id ON devices (room_id);

CREATE TABLE sensors (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    name text NOT NULL,
    metric text NOT NULL,
    unit text,
    data_type text,
    device_id uuid NOT NULL,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_sensors_device_id ON sensors (device_id);

CREATE TABLE thresholds (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    name text,
    min_value double precision NOT NULL,
    max_value double precision NOT NULL,
    debounce_seconds bigint NOT NULL DEFAULT 5,
    severity bigint NOT NULL DEFAULT 3,
    enabled boolean NOT NULL DEFAULT true,
    sensor_id uuid NOT NULL,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_thresholds_sensor_id ON thresholds (sensor_id);

CREATE TABLE alarms (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    code text,
    title text,
    message text,
    severity text,
    open boolean NOT NULL DEFAULT true,
    acknowledged boolean NOT NULL DEFAULT false,
    acknowledged_at timestamptz,
    triggered_at timestamptz NOT NULL,
    resolved_at timestamptz,
    device_key text,
    metric text,
    value double precision,
    threshold_min double precision,
    threshold_max double precision
);

CREATE INDEX idx_alarms_device_open_triggered ON alarms (device_key, open, triggered_at);

CREATE TABLE cameras (
    id bigserial PRIMARY KEY,
    room_id text,
    code varchar(64) NOT NULL,
    name varchar(128) NOT NULL,
    rtsp_url varchar(512),
    http_url varchar(512),
    username varchar(64),
    password_enc varchar(255),
    position varchar(255),
    resolution varchar(32),
    fps bigint,
    is_online boolean NOT NULL DEFAULT true,
    gb_device_id varchar(20),
    gb_channel_id varchar(20),
    gb_auth_id varchar(20),
    gb_auth_password varchar(255),
    gb_stream_type varchar(10),
    gb_transport varchar(10),
    gb_alarm_channel_id varchar(20),
    gb_voice_channel_id varchar(20),
    gb_manufacturer varchar(64),
    manufacturer_id varchar(64),
    enabled boolean NOT NULL DEFAULT true,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_cameras_room_id ON cameras (room_id);

CREATE TABLE video_clips (
    id bigserial PRIMARY KEY,
    trigger text NOT NULL DEFAULT 'alarm',
    file_path text,
    duration_sec real NOT NULL DEFAULT 0,
    start_at timestamptz NOT NULL,
    end_at timestamptz,
    resolution text,
    size_bytes bigint,
    notes text,
    camera_id text NOT NULL,
    room_id text,
    alarm_id text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now(),
    s3_bucket text,
    s3_key text
);

CREATE INDEX idx_video_clips_alarm_id ON video_clips (alarm_id);
CREATE INDEX idx_video_clips_room_id ON video_clips (room_id);
CREATE INDEX idx_video_clips_camera_id ON video_clips (camera_id);

CREATE TABLE audit_logs (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id uuid,
    username text,
    action text NOT NULL,
    resource text,
    target_id text,
    description text,
    ip_address text,
    user_agent text,
    metadata jsonb,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_audit_logs_resource_target ON audit_logs (resource, target_id);
CREATE INDEX idx_audit_logs_action_created ON audit_logs (action, created_at);
CREATE INDEX idx_audit_logs_user_created ON audit_logs (user_id, created_at);

CREATE TABLE telemetry (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    device_key text NOT NULL,
    metric text NOT NULL,
    value double precision NOT NULL,
    timestamp timestamptz NOT NULL
);

CREATE INDEX idx_telemetry_device_timestamp ON telemetry (device_key, timestamp);

CREATE TABLE permissions (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    code text NOT NULL,
    name text NOT NULL,
    description text,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE UNIQUE INDEX idx_permissions_code ON permissions (code);

CREATE TABLE role_permissions (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    role text NOT NULL,
    permission_id uuid NOT NULL,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE UNIQUE INDEX idx_role_permissions_role_code ON role_permissions (role, permission_id);

CREATE TABLE diseases (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    name varchar(64) NOT NULL,
    category varchar(32) NOT NULL,
    pathogen text NOT NULL,
    transmission text NOT NULL,
    medium text NOT NULL,
    incubation text NOT NULL,
    symptoms text NOT NULL,
    high_risk_stage text NOT NULL,
    high_risk_condition text NOT NULL,
    lethal_time text NOT NULL,
    spread_trend text NOT NULL,
    recurrence text NOT NULL,
    detection text NOT NULL,
    prevention text NOT NULL,
    image_url varchar(512),
    sort_order bigint NOT NULL DEFAULT 0,
    enabled boolean NOT NULL DEFAULT true,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_diseases_category ON diseases (category);

CREATE TABLE knowledge_articles (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    kind varchar(32) NOT NULL,
    title varchar(128) NOT NULL,
    summary text NOT NULL,
    content text NOT NULL,
    sort_order bigint NOT NULL DEFAULT 0,
    enabled boolean NOT NULL DEFAULT true,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_knowledge_articles_kind ON knowledge_articles (kind);

CREATE TABLE inspection_records (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id uuid,
    room_id uuid,
    image_url varchar(512),
    detections jsonb,
    risk_score double precision,
    risk_level varchar(16),
    ai_status varchar(16) NOT NULL DEFAULT 'done',
    idempotency_key varchar(128),
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE UNIQUE INDEX idx_inspection_records_idempotency_key ON inspection_records (idempotency_key);
CREATE INDEX idx_inspection_records_room_id ON inspection_records (room_id);
CREATE INDEX idx_inspection_records_user_id ON inspection_records (user_id);

CREATE TABLE trays (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    name varchar(64) NOT NULL,
    code varchar(64),
    position varchar(128),
    room_id uuid NOT NULL,
    enabled boolean NOT NULL DEFAULT true,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_trays_room_id ON trays (room_id);

CREATE TABLE batches (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    room_id uuid NOT NULL,
    name varchar(64) NOT NULL,
    variety varchar(64),
    source varchar(128),
    seed_batch_no varchar(64),
    quarantine_no varchar(64),
    instar bigint,
    entered_at timestamptz,
    mount_at timestamptz,
    status varchar(16) NOT NULL DEFAULT 'rearing',
    note text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_batches_room_id ON batches (room_id);

CREATE TABLE rearing_records (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    batch_id uuid NOT NULL,
    record_date timestamptz NOT NULL,
    instar bigint,
    mulberry_source varchar(128),
    density varchar(64),
    note text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_rearing_records_batch_id ON rearing_records (batch_id);

CREATE TABLE wechat_bindings (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id uuid NOT NULL,
    open_id varchar(128) NOT NULL,
    authorized_templates jsonb,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE UNIQUE INDEX idx_wechat_bindings_open_id ON wechat_bindings (open_id);
CREATE UNIQUE INDEX idx_wechat_bindings_user_id ON wechat_bindings (user_id);

CREATE TABLE weather_alerts (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    disease varchar(64) NOT NULL,
    level varchar(16) NOT NULL,
    reason text NOT NULL,
    snapshot jsonb,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE lamp_tests (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    method varchar(32) NOT NULL DEFAULT 'lamp',
    room_id uuid,
    batch_id uuid,
    diseases jsonb,
    status varchar(16) NOT NULL DEFAULT 'pending',
    sample_info varchar(255),
    result varchar(16),
    result_image_url varchar(512),
    operator_id uuid,
    resulted_at timestamptz,
    cross_status varchar(16) NOT NULL DEFAULT 'pending',
    cross_reason text,
    extra_data jsonb,
    note text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_lamp_tests_batch_id ON lamp_tests (batch_id);
CREATE INDEX idx_lamp_tests_room_id ON lamp_tests (room_id);

CREATE TABLE lamp_test_steps (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    lamp_test_id uuid NOT NULL,
    step_no bigint NOT NULL,
    name varchar(64) NOT NULL,
    done boolean NOT NULL DEFAULT false,
    done_at timestamptz,
    note text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_lamp_test_steps_lamp_test_id ON lamp_test_steps (lamp_test_id);

CREATE TABLE consumables (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    name varchar(64) NOT NULL,
    category varchar(32) NOT NULL,
    spec varchar(128),
    quantity double precision NOT NULL,
    unit varchar(32),
    min_quantity double precision NOT NULL,
    expiry_date timestamptz,
    supplier varchar(128),
    note text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_consumables_category ON consumables (category);

CREATE TABLE consultations (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    room_id uuid,
    batch_id uuid,
    lamp_test_id uuid,
    title varchar(128) NOT NULL,
    summary text,
    snapshot jsonb,
    status varchar(16) NOT NULL DEFAULT 'pending',
    expert_id uuid,
    opinion text,
    plan text,
    resolved_at timestamptz,
    archived_at timestamptz,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_consultations_lamp_test_id ON consultations (lamp_test_id);
CREATE INDEX idx_consultations_batch_id ON consultations (batch_id);
CREATE INDEX idx_consultations_room_id ON consultations (room_id);

CREATE TABLE spectrum_entries (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    disease varchar(64) NOT NULL,
    source varchar(128),
    data_url varchar(512),
    note text,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE trace_records (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    room_id uuid,
    lamp_test_id uuid,
    consultation_id uuid,
    disease varchar(64) NOT NULL,
    status varchar(16) NOT NULL DEFAULT 'pending',
    origin varchar(32),
    confidence double precision,
    auto_report jsonb,
    checklist jsonb,
    analysis_report jsonb,
    expert_note text,
    lab_note text,
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX idx_trace_records_consultation_id ON trace_records (consultation_id);
CREATE INDEX idx_trace_records_lamp_test_id ON trace_records (lamp_test_id);
CREATE INDEX idx_trace_records_room_id ON trace_records (room_id);
