CREATE TABLE profile (
  id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY
  , email TEXT NOT NULL UNIQUE
  , name TEXT NOT NULL
  , type TEXT NOT NULL CHECK (type IN ('client', 'manager', 'admin'))
  , client_id BIGINT UNIQUE GENERATED ALWAYS AS (CASE WHEN type = 'client' THEN id END) STORED
  , manager_id BIGINT UNIQUE GENERATED ALWAYS AS (CASE WHEN type = 'manager' THEN id END) STORED
  , created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE profile_detail (
  profile_id BIGINT PRIMARY KEY REFERENCES profile (id)
  , bio TEXT
  , phone TEXT
);

CREATE TABLE address (
  id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY
  , profile_id BIGINT NOT NULL REFERENCES profile (id)
  , city TEXT NOT NULL
  , street TEXT NOT NULL
  , UNIQUE (id, profile_id)
);

CREATE INDEX address_profile_id_idx ON address (profile_id);

CREATE TABLE item (
  id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY
  , parent_item_id BIGINT REFERENCES item (id)
  , sku TEXT NOT NULL UNIQUE
  , name TEXT NOT NULL
  , price NUMERIC(12, 2) NOT NULL DEFAULT 0
);

CREATE INDEX item_parent_item_id_idx ON item (parent_item_id);

CREATE TABLE document (
  id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY
  , client_id BIGINT NOT NULL REFERENCES profile (client_id)
  , manager_id BIGINT REFERENCES profile (manager_id)
  , delivery_address_id BIGINT
  , doc_number TEXT NOT NULL UNIQUE
  , issued_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  -- the _rel suffix sets the relation role explicitly: delivery_address(document)
  , CONSTRAINT delivery_address_rel
    FOREIGN KEY (delivery_address_id, client_id) REFERENCES address (id, profile_id)
);

CREATE INDEX document_client_id_idx ON document (client_id);
CREATE INDEX document_manager_id_idx ON document (manager_id);
CREATE INDEX document_delivery_address_id_idx ON document (delivery_address_id);

CREATE TABLE document_item (
  document_id BIGINT NOT NULL REFERENCES document (id)
  , item_id BIGINT NOT NULL REFERENCES item (id)
  , quantity INT NOT NULL DEFAULT 1 CHECK (quantity > 0)
  , PRIMARY KEY (document_id, item_id)
);

CREATE INDEX document_item_item_id_idx ON document_item (item_id);

INSERT INTO profile (email, name, type) VALUES
  ('c1@x.io', 'Client One', 'client')
  , ('c2@x.io', 'Client Two', 'client')
  , ('m@x.io', 'Manager', 'manager')
  , ('c3@x.io', 'Client Three', 'client')
;

INSERT INTO profile_detail (profile_id, bio, phone) VALUES
  (1, 'Regular buyer', '+49 30 1111111')
  , (3, 'Sales manager', '+49 30 5555555')
;

INSERT INTO address (profile_id, city, street) VALUES
  (1, 'Berlin', 'Alexanderplatz 1')
  , (2, 'Paris', 'Rue de Rivoli 2')
;

INSERT INTO item (parent_item_id, sku, name, price) VALUES
  (NULL, 'SKU-1', 'Laptop', 1200)
  , (1, 'SKU-2', 'Mouse', 25)
  , (1, 'SKU-3', 'Keyboard', 90)
  , (2, 'SKU-4', 'Mouse Pro', 45)
;

INSERT INTO document (client_id, manager_id, delivery_address_id, doc_number, issued_at) VALUES
  (1, 3, 1, 'DOC-1', '2026-07-01')
  , (1, NULL, NULL, 'DOC-2', '2026-07-15')
  , (2, 3, 2, 'DOC-3', '2026-07-20')
;

INSERT INTO document_item (document_id, item_id, quantity) VALUES
  (1, 1, 1)
  , (1, 2, 2)
  , (2, 3, 1)
  , (3, 2, 5)
;
