-- CableGUI v3 initial schema. See docs/design.md §2.

-- A project IS a drawing. LOFT and OFFICE are separate projects.
-- One project ↔ one .excalidraw file in mExDraw.
CREATE TABLE projects (
    id              INTEGER PRIMARY KEY,
    name            TEXT NOT NULL UNIQUE,
    drawing_name    TEXT NOT NULL,
    description     TEXT NOT NULL DEFAULT '',
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now'))
);

-- Cable types: GLOBAL legend, shared across all projects.
-- Seeded once below with the 5 defaults.
CREATE TABLE cable_types (
    id              INTEGER PRIMARY KEY,
    name            TEXT NOT NULL UNIQUE,
    color           TEXT NOT NULL,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now'))
);

CREATE TABLE frames (
    id              INTEGER PRIMARY KEY,
    project_id      INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    name            TEXT NOT NULL,
    x               REAL NOT NULL DEFAULT 0,
    y               REAL NOT NULL DEFAULT 0,
    width           REAL NOT NULL DEFAULT 1200,
    height          REAL NOT NULL DEFAULT 800,
    excalidraw_id   TEXT,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now')),
    UNIQUE (project_id, name),
    UNIQUE (project_id, excalidraw_id)
);
CREATE INDEX frames_project_idx ON frames(project_id);

CREATE TABLE devices (
    id              INTEGER PRIMARY KEY,
    project_id      INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    frame_id        INTEGER REFERENCES frames(id) ON DELETE SET NULL,
    name            TEXT NOT NULL,
    color           TEXT NOT NULL DEFAULT '#1e1e1e',
    x               REAL NOT NULL,
    y               REAL NOT NULL,
    width           REAL NOT NULL,
    height          REAL NOT NULL,
    excalidraw_id   TEXT,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now')),
    UNIQUE (project_id, name),
    UNIQUE (project_id, excalidraw_id)
);
CREATE INDEX devices_project_idx ON devices(project_id);
CREATE INDEX devices_frame_idx   ON devices(frame_id);

CREATE TABLE ports (
    id              INTEGER PRIMARY KEY,
    project_id      INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    device_id       INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
    type_id         INTEGER NOT NULL REFERENCES cable_types(id) ON DELETE RESTRICT,
    label           TEXT,
    x_offset        REAL NOT NULL,
    y_offset        REAL NOT NULL,
    excalidraw_id   TEXT,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now')),
    UNIQUE (project_id, excalidraw_id)
);
CREATE INDEX ports_project_idx ON ports(project_id);
CREATE INDEX ports_device_idx  ON ports(device_id);
CREATE INDEX ports_type_idx    ON ports(type_id);

CREATE TABLE io_markers (
    id              INTEGER PRIMARY KEY,
    project_id      INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    frame_id        INTEGER REFERENCES frames(id) ON DELETE SET NULL,
    label           TEXT NOT NULL DEFAULT 'IO',
    x               REAL NOT NULL,
    y               REAL NOT NULL,
    excalidraw_id   TEXT,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now')),
    UNIQUE (project_id, excalidraw_id)
);
CREATE INDEX io_markers_project_idx ON io_markers(project_id);
CREATE INDEX io_markers_frame_idx   ON io_markers(frame_id);

CREATE TABLE cables (
    id              INTEGER PRIMARY KEY,
    project_id      INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    type_id         INTEGER NOT NULL REFERENCES cable_types(id) ON DELETE RESTRICT,
    label           TEXT,
    from_port_id    INTEGER REFERENCES ports(id)      ON DELETE SET NULL,
    from_device_id  INTEGER REFERENCES devices(id)    ON DELETE SET NULL,
    from_io_id      INTEGER REFERENCES io_markers(id) ON DELETE SET NULL,
    to_port_id      INTEGER REFERENCES ports(id)      ON DELETE SET NULL,
    to_device_id    INTEGER REFERENCES devices(id)    ON DELETE SET NULL,
    to_io_id        INTEGER REFERENCES io_markers(id) ON DELETE SET NULL,
    excalidraw_id   TEXT,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now')),
    CHECK (
        (from_port_id IS NOT NULL) + (from_device_id IS NOT NULL) + (from_io_id IS NOT NULL) = 1
    ),
    CHECK (
        (to_port_id IS NOT NULL) + (to_device_id IS NOT NULL) + (to_io_id IS NOT NULL) = 1
    ),
    UNIQUE (project_id, excalidraw_id)
);
CREATE INDEX cables_project_idx     ON cables(project_id);
CREATE INDEX cables_from_port_idx   ON cables(from_port_id);
CREATE INDEX cables_to_port_idx     ON cables(to_port_id);
CREATE INDEX cables_from_device_idx ON cables(from_device_id);
CREATE INDEX cables_to_device_idx   ON cables(to_device_id);
CREATE INDEX cables_type_idx        ON cables(type_id);

CREATE TABLE bundles (
    id              INTEGER PRIMARY KEY,
    project_id      INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
    name            TEXT NOT NULL,
    auto            INTEGER NOT NULL DEFAULT 0,
    created_at      TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at      TEXT NOT NULL DEFAULT (datetime('now')),
    UNIQUE (project_id, name)
);
CREATE INDEX bundles_project_idx ON bundles(project_id);

CREATE TABLE bundle_cables (
    bundle_id       INTEGER NOT NULL REFERENCES bundles(id) ON DELETE CASCADE,
    cable_id        INTEGER NOT NULL REFERENCES cables(id)  ON DELETE CASCADE,
    PRIMARY KEY (bundle_id, cable_id)
);
CREATE INDEX bundle_cables_cable_idx ON bundle_cables(cable_id);

-- Seed the 5 default cable types, once.
INSERT INTO cable_types (name, color) VALUES
    ('Power', '#e03131'),
    ('USB',   '#2f9e44'),
    ('HDMI',  '#1971c2'),
    ('DP',    '#9c36b5'),
    ('RJ45',  '#ffd500');
