-- Meshkee CMS — initial schema
-- Tables: users, businesses, domains

-- Reusable trigger to keep updated_at in sync
CREATE OR REPLACE FUNCTION set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- ---------------------------------------------------------------------------
-- users
-- ---------------------------------------------------------------------------
CREATE TABLE users (
  id                BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  cell_number       VARCHAR(20) NOT NULL,
  password_hash     VARCHAR(255) NOT NULL,
  email             VARCHAR(255),
  first_name        VARCHAR(100),
  last_name         VARCHAR(100),
  is_active         BOOLEAN NOT NULL DEFAULT TRUE,
  cell_verified_at  TIMESTAMPTZ,
  last_login_at     TIMESTAMPTZ,
  created_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT users_cell_number_unique UNIQUE (cell_number),
  CONSTRAINT users_cell_number_format CHECK (cell_number ~ '^\+[1-9]\d{6,14}$'),
  CONSTRAINT users_email_format_optional CHECK (
    email IS NULL OR email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'
  )
);

CREATE INDEX idx_users_cell_number ON users (cell_number);
CREATE INDEX idx_users_is_active ON users (is_active) WHERE is_active = TRUE;

CREATE TRIGGER users_set_updated_at
  BEFORE UPDATE ON users
  FOR EACH ROW
  EXECUTE FUNCTION set_updated_at();

-- ---------------------------------------------------------------------------
-- businesses (created by super admin — no direct user owner column)
-- ---------------------------------------------------------------------------
CREATE TABLE businesses (
  id              BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  name            VARCHAR(255) NOT NULL,
  slug            VARCHAR(100) NOT NULL,
  description     TEXT,
  settings        JSONB NOT NULL DEFAULT '{}',
  is_active       BOOLEAN NOT NULL DEFAULT TRUE,
  created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT businesses_slug_unique UNIQUE (slug),
  CONSTRAINT businesses_slug_format CHECK (slug ~ '^[a-z0-9]+(?:-[a-z0-9]+)*$')
);

CREATE INDEX idx_businesses_is_active ON businesses (is_active) WHERE is_active = TRUE;

CREATE TRIGGER businesses_set_updated_at
  BEFORE UPDATE ON businesses
  FOR EACH ROW
  EXECUTE FUNCTION set_updated_at();

-- ---------------------------------------------------------------------------
-- domains (many per business)
-- ---------------------------------------------------------------------------
CREATE TABLE domains (
  id              BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  business_id     BIGINT NOT NULL,
  host            VARCHAR(253) NOT NULL,
  is_primary      BOOLEAN NOT NULL DEFAULT FALSE,
  is_verified     BOOLEAN NOT NULL DEFAULT FALSE,
  verified_at     TIMESTAMPTZ,
  ssl_enabled     BOOLEAN NOT NULL DEFAULT FALSE,
  created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT domains_host_unique UNIQUE (host),
  CONSTRAINT domains_business_id_fkey
    FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
  CONSTRAINT domains_host_format CHECK (
    host ~ '^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$'
    OR host ~ '^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$'
  )
);

CREATE INDEX idx_domains_business_id ON domains (business_id);
CREATE INDEX idx_domains_host ON domains (host);
CREATE INDEX idx_domains_business_primary ON domains (business_id) WHERE is_primary = TRUE;

CREATE UNIQUE INDEX idx_domains_one_primary_per_business
  ON domains (business_id)
  WHERE is_primary = TRUE;

CREATE TRIGGER domains_set_updated_at
  BEFORE UPDATE ON domains
  FOR EACH ROW
  EXECUTE FUNCTION set_updated_at();
