-- Multi-library support.
-- Adds `libraries` registry table and a `library_id` column on per-instance
-- metadata tables. Renames `file_path` / `photo_name` to `rel_path` for
-- semantic clarity (values already stored relative to BASE_PATH).
-- Adds `content_hash` + `size_bytes` to `image_exif` to support
-- content-based dedup of thumbnails and HLS output across libraries.
--
-- SQLite cannot alter column constraints in place, so per-instance tables
-- are recreated following the idiom established in
-- 2026-04-02-000000_photo_insights_history/up.sql. Existing row `id`s are
-- preserved so foreign keys (entity_facts.source_insight_id, etc.) remain
-- valid after migration.

PRAGMA foreign_keys=OFF;

-- ---------------------------------------------------------------------------
-- 1. Libraries registry.
-- Seeded with a placeholder for the primary library; AppState patches
-- `root_path` from the BASE_PATH env var on first boot. Subsequent
-- prod-to-dev DB syncs update this row via a single SQL UPDATE.
-- ---------------------------------------------------------------------------
CREATE TABLE libraries (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    name TEXT NOT NULL UNIQUE,
    root_path TEXT NOT NULL,
    created_at BIGINT NOT NULL
);

INSERT INTO libraries (id, name, root_path, created_at)
VALUES (1, 'main', 'BASE_PATH_PLACEHOLDER', strftime('%s','now'));

-- ---------------------------------------------------------------------------
-- 2. image_exif: + library_id, file_path → rel_path, + content_hash/size_bytes.
-- ---------------------------------------------------------------------------
CREATE TABLE image_exif_new (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    library_id INTEGER NOT NULL REFERENCES libraries(id),
    rel_path TEXT NOT NULL,

    -- Camera information
    camera_make TEXT,
    camera_model TEXT,
    lens_model TEXT,

    -- Image properties
    width INTEGER,
    height INTEGER,
    orientation INTEGER,

    -- GPS
    gps_latitude REAL,
    gps_longitude REAL,
    gps_altitude REAL,

    -- Capture settings
    focal_length REAL,
    aperture REAL,
    shutter_speed TEXT,
    iso INTEGER,
    date_taken BIGINT,

    -- Housekeeping
    created_time BIGINT NOT NULL,
    last_modified BIGINT NOT NULL,

    -- Content identity (backfilled by the `backfill_hashes` binary and by the watcher for new files)
    content_hash TEXT,
    size_bytes BIGINT,

    UNIQUE(library_id, rel_path)
);

INSERT INTO image_exif_new (
    id, library_id, rel_path,
    camera_make, camera_model, lens_model,
    width, height, orientation,
    gps_latitude, gps_longitude, gps_altitude,
    focal_length, aperture, shutter_speed, iso, date_taken,
    created_time, last_modified
)
SELECT
    id, 1, file_path,
    camera_make, camera_model, lens_model,
    width, height, orientation,
    gps_latitude, gps_longitude, gps_altitude,
    focal_length, aperture, shutter_speed, iso, date_taken,
    created_time, last_modified
FROM image_exif;

DROP TABLE image_exif;
ALTER TABLE image_exif_new RENAME TO image_exif;

CREATE INDEX idx_image_exif_rel_path      ON image_exif(rel_path);
CREATE INDEX idx_image_exif_camera        ON image_exif(camera_make, camera_model);
CREATE INDEX idx_image_exif_gps           ON image_exif(gps_latitude, gps_longitude);
CREATE INDEX idx_image_exif_date_taken    ON image_exif(date_taken);
CREATE INDEX idx_image_exif_date_path     ON image_exif(date_taken DESC, rel_path);
CREATE INDEX idx_image_exif_lib_date      ON image_exif(library_id, date_taken);
CREATE INDEX idx_image_exif_content_hash  ON image_exif(content_hash);

-- ---------------------------------------------------------------------------
-- 3. photo_insights: + library_id, file_path → rel_path.
-- Preserve `id` so entity_facts.source_insight_id FKs remain valid.
-- ---------------------------------------------------------------------------
CREATE TABLE photo_insights_new (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    library_id INTEGER NOT NULL REFERENCES libraries(id),
    rel_path TEXT NOT NULL,
    title TEXT NOT NULL,
    summary TEXT NOT NULL,
    generated_at BIGINT NOT NULL,
    model_version TEXT NOT NULL,
    is_current BOOLEAN NOT NULL DEFAULT 0,
    training_messages TEXT,
    approved BOOLEAN
);

INSERT INTO photo_insights_new (
    id, library_id, rel_path, title, summary, generated_at, model_version,
    is_current, training_messages, approved
)
SELECT
    id, 1, file_path, title, summary, generated_at, model_version,
    is_current, training_messages, approved
FROM photo_insights;

DROP TABLE photo_insights;
ALTER TABLE photo_insights_new RENAME TO photo_insights;

CREATE INDEX idx_photo_insights_rel_path ON photo_insights(rel_path);
CREATE INDEX idx_photo_insights_current  ON photo_insights(library_id, rel_path, is_current);

-- ---------------------------------------------------------------------------
-- 4. entity_photo_links: + library_id, file_path → rel_path.
-- Preserves entity FK; UNIQUE now includes library_id to allow the same
-- rel_path to link entities in multiple libraries independently.
-- ---------------------------------------------------------------------------
CREATE TABLE entity_photo_links_new (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    entity_id INTEGER NOT NULL,
    library_id INTEGER NOT NULL REFERENCES libraries(id),
    rel_path TEXT NOT NULL,
    role TEXT NOT NULL,
    CONSTRAINT fk_epl_entity FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,
    UNIQUE(entity_id, library_id, rel_path, role)
);

INSERT INTO entity_photo_links_new (id, entity_id, library_id, rel_path, role)
SELECT id, entity_id, 1, file_path, role FROM entity_photo_links;

DROP TABLE entity_photo_links;
ALTER TABLE entity_photo_links_new RENAME TO entity_photo_links;

CREATE INDEX idx_entity_photo_links_entity ON entity_photo_links(entity_id);
CREATE INDEX idx_entity_photo_links_photo  ON entity_photo_links(library_id, rel_path);

-- ---------------------------------------------------------------------------
-- 5. video_preview_clips: + library_id, file_path → rel_path.
-- ---------------------------------------------------------------------------
CREATE TABLE video_preview_clips_new (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    library_id INTEGER NOT NULL REFERENCES libraries(id),
    rel_path TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending',
    duration_seconds REAL,
    file_size_bytes INTEGER,
    error_message TEXT,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL,
    UNIQUE(library_id, rel_path)
);

INSERT INTO video_preview_clips_new (
    id, library_id, rel_path, status, duration_seconds, file_size_bytes,
    error_message, created_at, updated_at
)
SELECT
    id, 1, file_path, status, duration_seconds, file_size_bytes,
    error_message, created_at, updated_at
FROM video_preview_clips;

DROP TABLE video_preview_clips;
ALTER TABLE video_preview_clips_new RENAME TO video_preview_clips;

CREATE INDEX idx_preview_clips_rel_path ON video_preview_clips(rel_path);
CREATE INDEX idx_preview_clips_status   ON video_preview_clips(status);

-- ---------------------------------------------------------------------------
-- 6. favorites: path → rel_path. Library-agnostic (cross-library sharing).
-- ---------------------------------------------------------------------------
ALTER TABLE favorites RENAME COLUMN path TO rel_path;

DROP INDEX IF EXISTS idx_favorites_path;
DROP INDEX IF EXISTS idx_favorites_unique;
CREATE INDEX idx_favorites_rel_path ON favorites(rel_path);
CREATE UNIQUE INDEX idx_favorites_unique ON favorites(userid, rel_path);

-- ---------------------------------------------------------------------------
-- 7. tagged_photo: photo_name → rel_path. Library-agnostic.
-- Dedup first so the (rel_path, tag_id) unique index can be created safely.
-- ---------------------------------------------------------------------------
ALTER TABLE tagged_photo RENAME COLUMN photo_name TO rel_path;

DELETE FROM tagged_photo
WHERE id NOT IN (
    SELECT MIN(id) FROM tagged_photo GROUP BY rel_path, tag_id
);

DROP INDEX IF EXISTS idx_tagged_photo_photo_name;
DROP INDEX IF EXISTS idx_tagged_photo_count;
CREATE INDEX idx_tagged_photo_rel_path ON tagged_photo(rel_path);
CREATE UNIQUE INDEX idx_tagged_photo_relpath_tag ON tagged_photo(rel_path, tag_id);

PRAGMA foreign_keys=ON;

ANALYZE;
