-- Category variations & options (product categories only)
-- Variation types: color (predefined palette), size (user-defined), custom (user-defined name + values)

CREATE TYPE variation_type AS ENUM ('color', 'size', 'custom');

CREATE TABLE category_variations (
  id              BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  business_id     BIGINT NOT NULL,
  category_id     BIGINT NOT NULL,
  name            VARCHAR(255) NOT NULL,
  variation_type  variation_type NOT NULL,
  sort_order      INTEGER NOT NULL DEFAULT 0,
  created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT category_variations_business_id_fkey
    FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
  CONSTRAINT category_variations_category_id_fkey
    FOREIGN KEY (category_id) REFERENCES categories (id) ON DELETE CASCADE
);

CREATE UNIQUE INDEX category_variations_one_color_per_category
  ON category_variations (category_id) WHERE variation_type = 'color';

CREATE UNIQUE INDEX category_variations_one_size_per_category
  ON category_variations (category_id) WHERE variation_type = 'size';

CREATE UNIQUE INDEX category_variations_custom_name_per_category
  ON category_variations (category_id, name) WHERE variation_type = 'custom';

CREATE INDEX idx_category_variations_category_id ON category_variations (category_id);
CREATE INDEX idx_category_variations_business_id ON category_variations (business_id);

CREATE TRIGGER category_variations_set_updated_at
  BEFORE UPDATE ON category_variations
  FOR EACH ROW
  EXECUTE FUNCTION set_updated_at();

CREATE TABLE category_variation_options (
  id            BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  variation_id  BIGINT NOT NULL,
  label         VARCHAR(255) NOT NULL,
  value         VARCHAR(255) NOT NULL,
  color_hex     VARCHAR(7),
  sort_order    INTEGER NOT NULL DEFAULT 0,
  created_at    TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT category_variation_options_variation_id_fkey
    FOREIGN KEY (variation_id) REFERENCES category_variations (id) ON DELETE CASCADE,
  CONSTRAINT category_variation_options_unique_value
    UNIQUE (variation_id, value)
);

CREATE INDEX idx_category_variation_options_variation_id
  ON category_variation_options (variation_id);

-- Product variants (combinations of category variation options)
CREATE TABLE product_variants (
  id               BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  business_id      BIGINT NOT NULL,
  product_id       BIGINT NOT NULL,
  sku              VARCHAR(100),
  price            NUMERIC(12, 2),
  compare_at_price NUMERIC(12, 2),
  stock_quantity   INTEGER,
  is_active        BOOLEAN NOT NULL DEFAULT TRUE,
  sort_order       INTEGER NOT NULL DEFAULT 0,
  created_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT product_variants_business_id_fkey
    FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
  CONSTRAINT product_variants_product_id_fkey
    FOREIGN KEY (product_id) REFERENCES products (id) ON DELETE CASCADE,
  CONSTRAINT product_variants_stock_non_negative
    CHECK (stock_quantity IS NULL OR stock_quantity >= 0)
);

CREATE INDEX idx_product_variants_product_id ON product_variants (product_id);
CREATE INDEX idx_product_variants_business_id ON product_variants (business_id);

CREATE TRIGGER product_variants_set_updated_at
  BEFORE UPDATE ON product_variants
  FOR EACH ROW
  EXECUTE FUNCTION set_updated_at();

CREATE TABLE product_variant_selections (
  variant_id    BIGINT NOT NULL,
  variation_id  BIGINT NOT NULL,
  option_id     BIGINT NOT NULL,

  CONSTRAINT product_variant_selections_pkey PRIMARY KEY (variant_id, variation_id),
  CONSTRAINT product_variant_selections_variant_id_fkey
    FOREIGN KEY (variant_id) REFERENCES product_variants (id) ON DELETE CASCADE,
  CONSTRAINT product_variant_selections_variation_id_fkey
    FOREIGN KEY (variation_id) REFERENCES category_variations (id) ON DELETE RESTRICT,
  CONSTRAINT product_variant_selections_option_id_fkey
    FOREIGN KEY (option_id) REFERENCES category_variation_options (id) ON DELETE RESTRICT,
  CONSTRAINT product_variant_selections_unique_option
    UNIQUE (variant_id, option_id)
);

CREATE INDEX idx_product_variant_selections_option_id
  ON product_variant_selections (option_id);
