-- 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);

-- Cached Discogs catalog for enrichment — RecordGod's OWN copy of just the releases it stocks,
-- so the store is self-contained: no live dependency on the full Discogs dump OR dealgod's DB.
-- Populated by build_disc_cache.py from the full mirror on ultra.
CREATE TABLE IF NOT EXISTS disc_cache (
    release_id bigint PRIMARY KEY,
    title      text,
    artist     text,
    thumb      text,
    weight     int
);

-- Encrypted credential vault. Values are Fernet ciphertext; the key lives in the environment
-- (RECORDGOD_SECRET_KEY), never here. Woo/Discogs/Cloudflare/DealGod tokens land here via /settings.
CREATE TABLE IF NOT EXISTS app_secret (
    name       text PRIMARY KEY,
    value_enc  bytea NOT NULL,
    updated_at timestamptz NOT NULL DEFAULT now()
);

-- POS customers (from wp_rmp_disc_sales_customers) — the counter's customer dropdown + add-new.
CREATE TABLE IF NOT EXISTS customer (
    id          bigint PRIMARY KEY,
    wp_user_id  bigint,
    first_name  text NOT NULL DEFAULT '',
    last_name   text DEFAULT '',
    email       text,
    phone       text,
    address     text,
    is_guest    boolean NOT NULL DEFAULT false,
    created_at  timestamptz DEFAULT now()
);
CREATE INDEX IF NOT EXISTS customer_name_idx  ON customer (lower(first_name), lower(last_name));
CREATE INDEX IF NOT EXISTS customer_email_idx ON customer (lower(email));

-- Named discounts / promotions (from wp_rmp_disc_sales_discounts) — the Promotions tab + POS promo picker.
CREATE TABLE IF NOT EXISTS sales_discount (
    id            bigint PRIMARY KEY,
    name          text NOT NULL,
    percentage    numeric(5,2) NOT NULL DEFAULT 0,
    is_active     boolean NOT NULL DEFAULT true,
    manual_active boolean NOT NULL DEFAULT false,   -- currently switched on at the counter
    discount_type text DEFAULT 'manual',            -- manual|promotion|tax
    description   text,
    bubble_text   text,
    bubble_color  text,
    start_at      timestamptz,
    end_at        timestamptz,
    created_at    timestamptz DEFAULT now()
);

-- Sales settings (from wp_rmp_disc_sales_settings) — currency / tax / default discount, key-value.
CREATE TABLE IF NOT EXISTS sales_setting (
    setting_key   text PRIMARY KEY,
    setting_value text,
    is_active     boolean NOT NULL DEFAULT true,
    updated_at    timestamptz DEFAULT now()
);

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