-- Chattyness Domain Types
-- PostgreSQL 18 with PostGIS
--
-- Custom domain types with constraints for data validation
-- Uses PostGIS GEOMETRY with SRID 0 for virtual 2D coordinate system
-- Load via: psql -f schema/types/002_domains.sql

\set ON_ERROR_STOP on

BEGIN;

-- =============================================================================
-- Common Domains
-- =============================================================================

-- Percentage stored as REAL (0.0 to 1.0)
CREATE DOMAIN public.percentage AS REAL
    CHECK (VALUE >= 0.0 AND VALUE <= 1.0);
COMMENT ON DOMAIN public.percentage IS 'Percentage value stored as 0.0-1.0 REAL';

-- Non-empty text (prevents empty strings where we need content)
CREATE DOMAIN public.nonempty_text AS TEXT
    CHECK (length(trim(VALUE)) > 0);
COMMENT ON DOMAIN public.nonempty_text IS 'Text that cannot be empty or whitespace-only';

-- Username format (lowercase alphanumeric with underscores)
CREATE DOMAIN auth.username AS TEXT
    CHECK (VALUE ~ '^[a-z][a-z0-9_]{2,29}$');
COMMENT ON DOMAIN auth.username IS 'Valid username: 3-30 chars, starts with letter, alphanumeric and underscores';

-- Display name (visible name, more permissive)
CREATE DOMAIN public.display_name AS TEXT
    CHECK (length(trim(VALUE)) BETWEEN 1 AND 50);
COMMENT ON DOMAIN public.display_name IS 'Visible display name, 1-50 characters';

-- Slug for URLs (realm names, scene names)
CREATE DOMAIN public.slug AS TEXT
    CHECK (VALUE ~ '^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$' OR VALUE ~ '^[a-z0-9]{1,2}$');
COMMENT ON DOMAIN public.slug IS 'URL-safe slug: 1-50 chars, lowercase alphanumeric and hyphens';

-- Email address (basic validation)
CREATE DOMAIN auth.email AS TEXT
    CHECK (VALUE ~ '^[^@\s]+@[^@\s]+\.[^@\s]+$');
COMMENT ON DOMAIN auth.email IS 'Basic email address format validation';

-- Color as hex string
CREATE DOMAIN public.hex_color AS TEXT
    CHECK (VALUE ~ '^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$');
COMMENT ON DOMAIN public.hex_color IS 'Hex color code (#RRGGBB or #RRGGBBAA)';

-- URL validation (basic)
CREATE DOMAIN public.url AS TEXT
    CHECK (VALUE ~ '^https?://[^\s]+$');
COMMENT ON DOMAIN public.url IS 'HTTP/HTTPS URL';

-- Asset path (relative path within storage)
CREATE DOMAIN public.asset_path AS TEXT
    CHECK (VALUE ~ '^[a-zA-Z0-9/_.-]+$' AND length(VALUE) <= 500);
COMMENT ON DOMAIN public.asset_path IS 'Valid asset storage path';

-- =============================================================================
-- PostGIS Spatial Domains (SRID 0 for virtual 2D world)
-- =============================================================================

-- Point in 2D virtual space (user position, prop position)
-- Using SRID 0 for non-geographic Cartesian coordinate system
CREATE DOMAIN public.virtual_point AS GEOMETRY(POINT, 0);
COMMENT ON DOMAIN public.virtual_point IS 'Point in 2D virtual space (SRID 0 Cartesian coordinates)';

-- 2D bounding box for scenes (defines playable area)
CREATE DOMAIN public.scene_bounds AS GEOMETRY(POLYGON, 0);
COMMENT ON DOMAIN public.scene_bounds IS 'Rectangular bounding box defining scene dimensions';

COMMIT;
