-- Migration 018: Customer portal auth + address/director book
-- Magic-link authentication — no passwords.
-- Customers are auto-created on first order; they can later log in with their email.

BEGIN;

-- ── Customers ─────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS customers (
  id            SERIAL PRIMARY KEY,
  email         TEXT NOT NULL UNIQUE,
  name          TEXT,
  phone         TEXT,
  company       TEXT,
  erpnext_id    TEXT,                          -- ERPNext Customer docname (synced after first order)
  created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at    TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_customers_email ON customers (email);

-- ── Customer sessions (magic-link tokens + JWT refresh) ────────────────────────
CREATE TABLE IF NOT EXISTS customer_sessions (
  id            SERIAL PRIMARY KEY,
  customer_id   INT NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
  token         TEXT NOT NULL UNIQUE,          -- opaque random token (magic link or session)
  token_type    TEXT NOT NULL DEFAULT 'magic', -- 'magic' | 'session'
  expires_at    TIMESTAMPTZ NOT NULL,
  used_at       TIMESTAMPTZ,                   -- magic tokens are single-use
  created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  ip_address    TEXT,
  user_agent    TEXT
);

CREATE INDEX IF NOT EXISTS idx_customer_sessions_token    ON customer_sessions (token);
CREATE INDEX IF NOT EXISTS idx_customer_sessions_customer ON customer_sessions (customer_id);

-- ── Saved addresses ───────────────────────────────────────────────────────────
-- Populated from completed orders. Customers can pick from these on new orders.
CREATE TABLE IF NOT EXISTS customer_addresses (
  id            SERIAL PRIMARY KEY,
  customer_id   INT NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
  label         TEXT,                          -- e.g. "Home", "Office", auto-generated
  street        TEXT NOT NULL,
  street2       TEXT,
  city          TEXT NOT NULL,
  province      TEXT,
  postal        TEXT,
  country       TEXT NOT NULL,
  is_default    BOOLEAN NOT NULL DEFAULT FALSE,
  source_order  TEXT,                          -- order_number this was first seen on
  created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_customer_addresses_customer ON customer_addresses (customer_id);

-- ── Saved directors / contacts ────────────────────────────────────────────────
-- People who have previously been listed as directors on formation/CRTC orders.
CREATE TABLE IF NOT EXISTS customer_directors (
  id            SERIAL PRIMARY KEY,
  customer_id   INT NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
  name          TEXT NOT NULL,
  citizenship   TEXT,
  address_id    INT REFERENCES customer_addresses(id) ON DELETE SET NULL,
  is_default    BOOLEAN NOT NULL DEFAULT FALSE,
  source_order  TEXT,
  created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_customer_directors_customer ON customer_directors (customer_id);

-- ── Link existing orders to customers (backfill on first login) ───────────────
-- We don't backfill immediately — on first login we match by email and link.
ALTER TABLE canada_crtc_orders
  ADD COLUMN IF NOT EXISTS customer_id INT REFERENCES customers(id) ON DELETE SET NULL;

CREATE INDEX IF NOT EXISTS idx_crtc_orders_customer ON canada_crtc_orders (customer_id);

ALTER TABLE orders
  ADD COLUMN IF NOT EXISTS customer_id INT REFERENCES customers(id) ON DELETE SET NULL;

-- ── Auto-update updated_at on customers ──────────────────────────────────────
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS customers_updated_at ON customers;
CREATE TRIGGER customers_updated_at
  BEFORE UPDATE ON customers
  FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

COMMIT;
