-- RecordGod schema v2.
-- ONE inventory table (vinyl + general goods unified), sales history, slim crates.
-- The Discogs CATALOG is deliberately NOT stored here — it lives in the discogs_full Postgres
-- mirror and is joined on release_id at read time. We keep the shop's OWN data only:
-- WowPlatter crammed a ~3.2M-row Discogs clone into the shop DB; RecordGod keeps ~40k real rows.

CREATE TABLE IF NOT EXISTS inventory (
    sku          text PRIMARY KEY,
    store_id     int  NOT NULL DEFAULT 1,             -- always 1 for now; the multi-shop seam
    kind         text NOT NULL DEFAULT 'vinyl',       -- vinyl|book|magazine|comic|card|game|other
    release_id   bigint,                              -- Discogs id (vinyl) → join discogs_full.release
    identifier   text,                                -- ISBN/UPC/barcode (general goods lookup key)
    title        text,                                -- denormalised cache; vinyl filled from mirror at intake
    price        numeric(10,2),
    qty          int  NOT NULL DEFAULT 1,
    in_stock     boolean NOT NULL DEFAULT true,       -- was enum('y','n')
    condition    text,                                -- media grade (vinyl) / condition desc (general)
    sleeve_cond  text,                                -- vinyl sleeve grade
    brand        text,
    model        text,
    weight_g     numeric(10,3),
    location     text,
    crate_id     int,
    slot_number  int,
    status       text DEFAULT 'publish',
    notes        text,
    product_url  text,
    -- DealGod price intel (the engine writes these)
    est_market_value  numeric(10,2),
    lowest_competitor numeric(10,2),
    target_price      numeric(10,2),
    priced_at         timestamptz,
    -- Square sync (Square/WP authoritative)
    square_item_id           text,
    square_catalog_object_id text,
    square_sku               text,
    square_synced_at         timestamptz,
    -- intake / staging (live owns sale-state; local owns intake — see RECORDGOD_PLAN.md §6)
    staged       boolean NOT NULL DEFAULT false,      -- true = intaken locally, not yet published live
    attributes   jsonb,                               -- per-kind extras (dimensions, etc.) — was longtext+CHECK
    images       jsonb,
    raw_json     jsonb,                               -- enrichment cache
    sold_date    timestamptz,
    created_at   timestamptz NOT NULL DEFAULT now(),
    updated_at   timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS inventory_release_idx    ON inventory (store_id, release_id) WHERE release_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS inventory_identifier_idx ON inventory (store_id, identifier) WHERE identifier IS NOT NULL;
CREATE INDEX IF NOT EXISTS inventory_instock_idx    ON inventory (store_id, in_stock) WHERE in_stock;
CREATE INDEX IF NOT EXISTS inventory_crate_idx      ON inventory (crate_id, slot_number);
CREATE INDEX IF NOT EXISTS inventory_staged_idx     ON inventory (staged) WHERE staged;

CREATE TABLE IF NOT EXISTS crate (
    id          int PRIMARY KEY,
    name        text NOT NULL,
    label_text  text,
    purpose     text DEFAULT 'stock',                 -- stock|spacer|display|returns|hold|sale
    notes       text
    -- 3D geometry (pos/rotation/mesh/genre-lists) intentionally stays in WowPlatter — front-end concern.
);

CREATE TABLE IF NOT EXISTS sales (
    id             bigint PRIMARY KEY,
    sale_number    text UNIQUE,
    customer_id    bigint,
    total          numeric(10,2) NOT NULL DEFAULT 0,  -- consolidated (WP had total + total_amount)
    tax_amount     numeric(10,2) NOT NULL DEFAULT 0,
    status         text DEFAULT 'pending',            -- consolidated (WP had status + payment_status)
    payment_method text,
    sale_date      timestamptz,
    created_at     timestamptz
    -- WooCommerce/WP stays authoritative for live sale-state; this is the reporting/analytics copy.
);
CREATE INDEX IF NOT EXISTS sales_date_idx ON sales (sale_date);

CREATE TABLE IF NOT EXISTS sale_items (
    id          bigint PRIMARY KEY,
    sale_id     bigint REFERENCES sales(id) ON DELETE CASCADE,
    sku         text,
    release_id  bigint,
    item_name   text,
    qty         int NOT NULL DEFAULT 1,
    unit_price  numeric(10,2) NOT NULL DEFAULT 0,
    line_total  numeric(10,2) NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS sale_items_sale_idx    ON sale_items (sale_id);
CREATE INDEX IF NOT EXISTS sale_items_release_idx ON sale_items (release_id);

-- pgvector (semantic search / "records like this" / newsletter copy): add when keyword search
-- measurably falls short, not before.
