-- WhereWoof canonical schema (Phase 1)
-- Source of truth until Laravel takes over migration ownership (Phase 4).
-- Applied by: make db-up (frontend/cmd/migrate)

CREATE TABLE IF NOT EXISTS users (
    id            BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    email         TEXT NOT NULL UNIQUE,
    password_hash TEXT NOT NULL,
    name          TEXT,
    phone         TEXT,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS tags (
    id          BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    tag_code    TEXT NOT NULL UNIQUE,      -- printed on QR + NFC, public identifier
    owner_id    BIGINT REFERENCES users(id),
    status      TEXT NOT NULL DEFAULT 'unset'
                CHECK (status IN ('unset', 'active', 'suspended', 'closed')),
    item_type   TEXT CHECK (item_type IN ('dog', 'cat', 'baggage', 'skis', 'other')),
    description TEXT,
    photo_url   TEXT,
    phone       TEXT,                       -- owner contact phone (shown via tel:)
    address     TEXT,
    notes       TEXT,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS scans (
    id              BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    tag_id          BIGINT NOT NULL REFERENCES tags(id),
    scanned_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    lat             DOUBLE PRECISION,
    lng             DOUBLE PRECISION,
    location_shared BOOLEAN NOT NULL DEFAULT FALSE,
    scanner_phone   TEXT,
    alert_sent      BOOLEAN NOT NULL DEFAULT FALSE
);

-- Phase 2: per-tag SMS alert control. Idempotent so existing DBs migrate cleanly.
ALTER TABLE tags ADD COLUMN IF NOT EXISTS sms_enabled BOOLEAN NOT NULL DEFAULT TRUE;

-- Phase 2.5: product templates + sales orders (mirrors 2014 products/online_orders model).
CREATE TABLE IF NOT EXISTS products (
    id          BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    sku         TEXT NOT NULL UNIQUE,
    name        TEXT NOT NULL,
    item_type   TEXT CHECK (item_type IN ('dog', 'cat', 'baggage', 'skis', 'other')),
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE IF NOT EXISTS orders (
    id          BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    account_id  BIGINT REFERENCES users(id),
    status      TEXT NOT NULL DEFAULT 'pending'
                CHECK (status IN ('pending', 'paid', 'lapsed', 'cancelled')),
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Tag → product / order linkage (populated by the Laravel admin, Phase 4).
ALTER TABLE tags ADD COLUMN IF NOT EXISTS product_id BIGINT REFERENCES products(id);
ALTER TABLE tags ADD COLUMN IF NOT EXISTS order_id BIGINT REFERENCES orders(id);

-- Phase 2.5: per-device anti-spam fingerprint on scans (idempotent).
ALTER TABLE scans ADD COLUMN IF NOT EXISTS fingerprint TEXT;

-- Phase 4: admin flag on users (idempotent).
ALTER TABLE users ADD COLUMN IF NOT EXISTS is_admin BOOLEAN NOT NULL DEFAULT FALSE;
-- Phase 4: Laravel session auth "remember me" token (idempotent).
ALTER TABLE users ADD COLUMN IF NOT EXISTS remember_token TEXT;

-- Phase 5-lite: client IP on scans for rate limiting (idempotent).
ALTER TABLE scans ADD COLUMN IF NOT EXISTS ip TEXT;

-- Phase 5.5: per-tag SMS metering (0 = unmetered/transitional).
ALTER TABLE tags ADD COLUMN IF NOT EXISTS sms_allocated INTEGER NOT NULL DEFAULT 0;
ALTER TABLE tags ADD COLUMN IF NOT EXISTS sms_used INTEGER NOT NULL DEFAULT 0;
ALTER TABLE tags ADD COLUMN IF NOT EXISTS sms_period_start DATE NOT NULL DEFAULT CURRENT_DATE;

-- Short URLs for SMS links (owner location pages).
CREATE TABLE IF NOT EXISTS url_shortened (
    code       TEXT PRIMARY KEY,
    scan_id    BIGINT NOT NULL REFERENCES scans(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Phase 5.5 quick wins: customer pause + order amounts (idempotent).
ALTER TABLE users ADD COLUMN IF NOT EXISTS paused BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE orders ADD COLUMN IF NOT EXISTS amount NUMERIC(10,2) NOT NULL DEFAULT 0;

-- Renewal tracking (lazy expiry): paid orders past renews_at are treated lapsed.
ALTER TABLE orders ADD COLUMN IF NOT EXISTS renews_at TIMESTAMPTZ;

-- Tag lifecycle: closed state (owner close / moved-from). Idempotent.
ALTER TABLE tags DROP CONSTRAINT IF EXISTS tags_status_check;
ALTER TABLE tags ADD CONSTRAINT tags_status_check CHECK (status IN ('unset','active','suspended','closed'));

-- Product photos (admin).
ALTER TABLE products ADD COLUMN IF NOT EXISTS photo_url TEXT;
