CREATE TABLE IF NOT EXISTS upp_exam_assets (
  ct_number text NOT NULL PRIMARY KEY,
  list_present boolean NOT NULL DEFAULT false,
  stl_present boolean NOT NULL DEFAULT false,
  patient_name text,
  patient_sex text,
  patient_age text,
  patient_id_masked text,
  exam_date timestamptz,
  task_created_at timestamptz,
  exam_description text,
  exam_device text,
  algorithm_model text,
  upp_status text,
  list_record_count integer NOT NULL DEFAULT 0,
  selected_list_record jsonb,
  list_records jsonb NOT NULL DEFAULT '[]'::jsonb,
  selected_source_case_dir text,
  selected_source_stl_dir text,
  processed_stl_dir text,
  stl_case_name text,
  stl_sequence_no integer,
  stl_file_count integer NOT NULL DEFAULT 0,
  stl_total_bytes bigint NOT NULL DEFAULT 0,
  stl_files jsonb NOT NULL DEFAULT '[]'::jsonb,
  stl_candidates jsonb NOT NULL DEFAULT '[]'::jsonb,
  updated_at timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT ck_upp_exam_assets_ct_number_present CHECK (btrim(ct_number) <> ''),
  CONSTRAINT ck_upp_exam_assets_ct_number_format CHECK (ct_number ~ '^D?CT[0-9]{8,}$')
);

DO $$
BEGIN
  IF to_regclass('public.upp_stl_files') IS NOT NULL
     AND NOT EXISTS (
       SELECT 1
       FROM information_schema.columns
       WHERE table_schema = 'public'
         AND table_name = 'upp_stl_files'
         AND column_name = 'file_names'
     )
  THEN
    CREATE TABLE IF NOT EXISTS upp_stl_files_row_detail_backup AS TABLE upp_stl_files;
    DROP TABLE upp_stl_files;
  END IF;
END $$;

CREATE TABLE IF NOT EXISTS upp_stl_files (
  ct_number text NOT NULL PRIMARY KEY REFERENCES upp_exam_assets(ct_number) ON DELETE CASCADE,
  file_count integer NOT NULL DEFAULT 0,
  total_bytes bigint NOT NULL DEFAULT 0,
  segment_names jsonb NOT NULL DEFAULT '[]'::jsonb,
  segment_families jsonb NOT NULL DEFAULT '[]'::jsonb,
  segment_categories jsonb NOT NULL DEFAULT '[]'::jsonb,
  file_names jsonb NOT NULL DEFAULT '[]'::jsonb,
  source_file_paths jsonb NOT NULL DEFAULT '[]'::jsonb,
  processed_file_paths jsonb NOT NULL DEFAULT '[]'::jsonb,
  files jsonb NOT NULL DEFAULT '[]'::jsonb,
  updated_at timestamptz NOT NULL DEFAULT now()
);

ALTER TABLE upp_exam_assets ALTER COLUMN ct_number SET NOT NULL;
ALTER TABLE upp_stl_files ALTER COLUMN ct_number SET NOT NULL;
ALTER TABLE upp_stl_files ADD COLUMN IF NOT EXISTS segment_families jsonb NOT NULL DEFAULT '[]'::jsonb;
ALTER TABLE upp_stl_files ADD COLUMN IF NOT EXISTS segment_categories jsonb NOT NULL DEFAULT '[]'::jsonb;

CREATE INDEX IF NOT EXISTS idx_upp_exam_assets_list_present ON upp_exam_assets(list_present);
CREATE INDEX IF NOT EXISTS idx_upp_exam_assets_stl_present ON upp_exam_assets(stl_present);
CREATE INDEX IF NOT EXISTS idx_upp_exam_assets_patient_name ON upp_exam_assets(patient_name);
CREATE INDEX IF NOT EXISTS idx_upp_exam_assets_exam_date ON upp_exam_assets(exam_date);
CREATE INDEX IF NOT EXISTS idx_upp_exam_assets_list_records_gin ON upp_exam_assets USING gin (list_records);
CREATE INDEX IF NOT EXISTS idx_upp_exam_assets_stl_files_gin ON upp_exam_assets USING gin (stl_files);
CREATE INDEX IF NOT EXISTS idx_upp_stl_files_segment_names_gin ON upp_stl_files USING gin (segment_names);
CREATE INDEX IF NOT EXISTS idx_upp_stl_files_segment_families_gin ON upp_stl_files USING gin (segment_families);
CREATE INDEX IF NOT EXISTS idx_upp_stl_files_segment_categories_gin ON upp_stl_files USING gin (segment_categories);
CREATE INDEX IF NOT EXISTS idx_upp_stl_files_file_names_gin ON upp_stl_files USING gin (file_names);
CREATE INDEX IF NOT EXISTS idx_upp_stl_files_files_gin ON upp_stl_files USING gin (files);

COMMENT ON TABLE upp_exam_assets IS 'UPP列表、STL重建结果、未来CT数据的CT号唯一资产索引';
COMMENT ON COLUMN upp_exam_assets.ct_number IS 'CT检查号，唯一索引键';
COMMENT ON COLUMN upp_exam_assets.list_records IS '来自UPP列表OCR的同CT号全部记录';
COMMENT ON COLUMN upp_exam_assets.selected_list_record IS '同CT号列表记录中按任务创建时间/检查时间选择的新记录';
COMMENT ON COLUMN upp_exam_assets.stl_candidates IS '同CT号全部候选STL目录，保留去重选择依据';
COMMENT ON COLUMN upp_exam_assets.stl_files IS '最终选中STL目录的文件清单';
COMMENT ON COLUMN upp_exam_assets.processed_stl_dir IS '规范化后的STL目录，目录名为CT号';
COMMENT ON TABLE upp_stl_files IS 'UPP最终选中STL文件聚合表，每个CT号唯一一行';
COMMENT ON COLUMN upp_stl_files.ct_number IS 'CT检查号，主键并关联upp_exam_assets.ct_number';
COMMENT ON COLUMN upp_stl_files.segment_names IS '最终选中STL文件的分割名称JSON数组';
COMMENT ON COLUMN upp_stl_files.segment_families IS '与segment_names同顺序的训练family JSON数组';
COMMENT ON COLUMN upp_stl_files.segment_categories IS '与segment_names同顺序的粗分类JSON数组';
COMMENT ON COLUMN upp_stl_files.file_names IS '最终选中STL文件名JSON数组';
COMMENT ON COLUMN upp_stl_files.files IS '最终选中STL文件完整明细JSON数组';
