-- Muyu CRM Graph Schema (PostgreSQL)
-- Long-term architecture baseline:
-- PostgreSQL (source of truth) -> CDC/Kafka -> Neo4j (graph analytics)

CREATE SCHEMA IF NOT EXISTS crm;
SET search_path TO crm, public;

-- ==================== Tenant and Identity ====================

CREATE TABLE IF NOT EXISTS tenant (
    id BIGSERIAL PRIMARY KEY,
    tenant_code VARCHAR(64) NOT NULL UNIQUE,
    tenant_name VARCHAR(128) NOT NULL,
    status SMALLINT NOT NULL DEFAULT 1,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS tenant_user (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL REFERENCES tenant(id),
    user_id VARCHAR(64) NOT NULL,
    role_key VARCHAR(64) NOT NULL DEFAULT 'user',
    is_primary BOOLEAN NOT NULL DEFAULT TRUE,
    status SMALLINT NOT NULL DEFAULT 1,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE (tenant_id, user_id)
);

CREATE INDEX IF NOT EXISTS idx_tenant_user_user_id ON tenant_user(user_id);

-- ==================== Graph Nodes and Edges ====================

CREATE TABLE IF NOT EXISTS relationship_type (
    id BIGSERIAL PRIMARY KEY,
    type_code VARCHAR(32) NOT NULL UNIQUE,
    type_name VARCHAR(64) NOT NULL,
    description TEXT NOT NULL DEFAULT '',
    status SMALLINT NOT NULL DEFAULT 1,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS tenant_relationship (
    id BIGSERIAL PRIMARY KEY,
    owner_tenant_id BIGINT NOT NULL REFERENCES tenant(id),
    from_tenant_id BIGINT NOT NULL REFERENCES tenant(id),
    to_tenant_id BIGINT NOT NULL REFERENCES tenant(id),
    relationship_type_id BIGINT NOT NULL REFERENCES relationship_type(id),
    status SMALLINT NOT NULL DEFAULT 1,
    valid_from TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    valid_to TIMESTAMPTZ NULL,
    source VARCHAR(32) NOT NULL DEFAULT 'manual',
    created_by VARCHAR(64) NOT NULL DEFAULT 'system',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CHECK (from_tenant_id <> to_tenant_id),
    CHECK (valid_to IS NULL OR valid_to > valid_from)
);

CREATE UNIQUE INDEX IF NOT EXISTS uk_tenant_relationship_version
ON tenant_relationship(owner_tenant_id, from_tenant_id, to_tenant_id, relationship_type_id, valid_from);

CREATE INDEX IF NOT EXISTS idx_tenant_relationship_from
ON tenant_relationship(owner_tenant_id, from_tenant_id, status);

CREATE INDEX IF NOT EXISTS idx_tenant_relationship_to
ON tenant_relationship(owner_tenant_id, to_tenant_id, status);

CREATE TABLE IF NOT EXISTS tenant_relationship_history (
    id BIGSERIAL PRIMARY KEY,
    relationship_id BIGINT NOT NULL REFERENCES tenant_relationship(id),
    change_type VARCHAR(32) NOT NULL,
    before_json JSONB,
    after_json JSONB,
    changed_by VARCHAR(64) NOT NULL DEFAULT 'system',
    changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_tenant_relationship_history_rel
ON tenant_relationship_history(relationship_id, changed_at DESC);

-- ==================== Seed Data ====================

INSERT INTO relationship_type(type_code, type_name, description)
VALUES
    ('SUPPLY', '供货关系', 'from_tenant 作为 to_tenant 的上游'),
    ('PURCHASE', '采购关系', 'from_tenant 向 to_tenant 发起采购'),
    ('OEM', '代工关系', '委托代工上下游关系')
ON CONFLICT (type_code) DO NOTHING;

-- ==================== One-hop Query Examples ====================
-- Upstream (who supplies current tenant):
-- SELECT r.from_tenant_id
-- FROM crm.tenant_relationship r
-- WHERE r.owner_tenant_id = $1
--   AND r.to_tenant_id = $2
--   AND r.status = 1;
--
-- Downstream (who current tenant supplies):
-- SELECT r.to_tenant_id
-- FROM crm.tenant_relationship r
-- WHERE r.owner_tenant_id = $1
--   AND r.from_tenant_id = $2
--   AND r.status = 1;
