-- Full Database Schema for GPI (PostgreSQL)
CREATE SCHEMA IF NOT EXISTS gpi;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- 1. Organizations
CREATE TABLE IF NOT EXISTS gpi.organizations (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    clerk_id TEXT UNIQUE, -- Legacy
    logto_id TEXT UNIQUE,
    name TEXT NOT NULL,
    is_banned BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 2. Users
CREATE TABLE IF NOT EXISTS gpi.users (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    clerk_id TEXT UNIQUE, -- Legacy
    logto_id TEXT UNIQUE,
    email TEXT UNIQUE NOT NULL,
    name TEXT NOT NULL,
    role TEXT CHECK (role IN ('guest', 'user', 'admin')) DEFAULT 'guest',
    is_banned BOOLEAN DEFAULT FALSE,
    last_seen_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 3. many-to-many user_organizations
CREATE TABLE IF NOT EXISTS gpi.user_organizations (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID REFERENCES gpi.users(id) ON DELETE CASCADE,
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    role TEXT CHECK (role IN ('guest', 'user', 'admin')) DEFAULT 'guest',
    is_banned BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE (user_id, organization_id)
);

-- 4. Technical Data Sheets (Fichas Técnicas)
CREATE TABLE IF NOT EXISTS gpi.technical_data_sheets (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    manufacturer TEXT,
    type TEXT,
    file_url TEXT,
    solids_volume DECIMAL,
    density DECIMAL,
    mixing_ratio TEXT,
    yield_theoretical DECIMAL,
    wft_min DECIMAL,
    wft_max DECIMAL,
    dft_min DECIMAL,
    dft_max DECIMAL,
    reducer TEXT,
    yield_factor DECIMAL DEFAULT 1.0,
    min_stock DECIMAL DEFAULT 0,
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 5. Projects
CREATE TABLE IF NOT EXISTS gpi.projects (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    client TEXT NOT NULL,
    start_date DATE,
    end_date DATE,
    technician TEXT,
    environment TEXT,
    weight_kg DECIMAL,
    status TEXT DEFAULT 'active',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 6. Parts
CREATE TABLE IF NOT EXISTS gpi.parts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
    description TEXT NOT NULL,
    dimensions TEXT,
    weight DECIMAL,
    type TEXT,
    area DECIMAL,
    complexity INTEGER,
    quantity INTEGER DEFAULT 1,
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 7. Painting Schemes
CREATE TABLE IF NOT EXISTS gpi.painting_schemes (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    type TEXT,
    coat TEXT, -- Primer, Intermediate, Finish
    solids_volume DECIMAL,
    yield_theoretical DECIMAL,
    eps_min DECIMAL,
    eps_max DECIMAL,
    dilution DECIMAL,
    manufacturer TEXT,
    color TEXT,
    notes TEXT,
    paint_id UUID REFERENCES gpi.technical_data_sheets(id),
    thinner_id UUID REFERENCES gpi.technical_data_sheets(id),
    color_hex TEXT,
    thinner_symbol TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 8. Application Records (Lotes de Pintura)
CREATE TABLE IF NOT EXISTS gpi.application_records (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
    coat_stage TEXT,
    piece_description TEXT,
    date DATE,
    operator TEXT,
    real_weight DECIMAL,
    volume_used DECIMAL,
    area_painted DECIMAL,
    wet_thickness_avg DECIMAL,
    dry_thickness_calc DECIMAL,
    real_yield DECIMAL,
    method TEXT,
    diluent_used DECIMAL,
    notes TEXT,
    items JSONB DEFAULT '[]', -- List of {partId, quantity}
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 9. Instruments
CREATE TABLE IF NOT EXISTS gpi.instruments (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    serial_number TEXT,
    type TEXT,
    last_calibration DATE,
    calibration_due DATE,
    status TEXT DEFAULT 'active',
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 10. Stock Items
CREATE TABLE IF NOT EXISTS gpi.stock_items (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    data_sheet_id UUID REFERENCES gpi.technical_data_sheets(id),
    batch_number TEXT NOT NULL,
    manufacturing_date DATE,
    expiration_date DATE,
    initial_quantity DECIMAL NOT NULL,
    current_quantity DECIMAL NOT NULL,
    unit TEXT DEFAULT 'L',
    location TEXT,
    status TEXT DEFAULT 'active',
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 11. Inspections
CREATE TABLE IF NOT EXISTS gpi.inspections (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    project_id UUID REFERENCES gpi.projects(id) ON DELETE CASCADE,
    application_record_id UUID REFERENCES gpi.application_records(id),
    stock_item_id UUID REFERENCES gpi.stock_items(id),
    instrument_id UUID REFERENCES gpi.instruments(id),
    type TEXT CHECK (type IN ('painting', 'surface_treatment')),
    date DATE,
    inspector TEXT,
    part_temperature DECIMAL,
    weight_kg DECIMAL,
    appearance TEXT, -- approved, rejected, notes
    defects TEXT,
    photos TEXT[] DEFAULT '{}',
    piece_description TEXT,
    eps_points DECIMAL[] DEFAULT '{}',
    adhesion_test TEXT,
    batch TEXT,
    treatment_executor TEXT,
    treatment_type TEXT,
    cleaning_degree TEXT,
    roughness_readings DECIMAL[] DEFAULT '{}',
    flash_rust TEXT,
    temperature DECIMAL,
    relative_humidity DECIMAL,
    period TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 12. Stock Movements
CREATE TABLE IF NOT EXISTS gpi.stock_movements (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    stock_item_id UUID REFERENCES gpi.stock_items(id) ON DELETE CASCADE,
    type TEXT CHECK (type IN ('in', 'out', 'adjust')),
    quantity DECIMAL NOT NULL,
    reason TEXT,
    project_id UUID REFERENCES gpi.projects(id),
    user_id TEXT, -- external_id
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 13. System Settings
CREATE TABLE IF NOT EXISTS gpi.system_settings (
    settings_id TEXT PRIMARY KEY DEFAULT 'global',
    app_name TEXT DEFAULT 'GPI',
    app_subtitle TEXT DEFAULT 'Gestão de Pintura Industrial',
    app_logo_url TEXT,
    updated_by TEXT,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 14. Notifications
CREATE TABLE IF NOT EXISTS gpi.notifications (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    recipient_id UUID REFERENCES gpi.users(id) ON DELETE CASCADE,
    title TEXT NOT NULL,
    message TEXT NOT NULL,
    type TEXT CHECK (type IN ('info', 'warning', 'error', 'success')) DEFAULT 'info',
    is_read BOOLEAN DEFAULT FALSE,
    is_archived BOOLEAN DEFAULT FALSE,
    archived_by UUID[] DEFAULT '{}',
    deleted_by UUID[] DEFAULT '{}',
    metadata JSONB DEFAULT '{}',
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 15. Yield Studies
CREATE TABLE IF NOT EXISTS gpi.yield_studies (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    data_sheet_id UUID REFERENCES gpi.technical_data_sheets(id),
    name TEXT NOT NULL,
    target_dft DECIMAL NOT NULL,
    dilution_percent DECIMAL DEFAULT 0,
    categories JSONB DEFAULT '[]',
    total_weight DECIMAL,
    estimated_paint_volume DECIMAL,
    estimated_reducer_volume DECIMAL,
    estimated_paint_volume_by_area DECIMAL,
    estimated_reducer_volume_by_area DECIMAL,
    average_complexity DECIMAL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 16. Stock Audit Logs
CREATE TABLE IF NOT EXISTS gpi.stock_audit_logs (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    stock_item_id UUID REFERENCES gpi.stock_items(id) ON DELETE CASCADE,
    movement_id UUID,
    movement_number INTEGER,
    user_id TEXT, -- external_id
    user_name TEXT,
    action TEXT NOT NULL,
    details TEXT,
    old_values JSONB,
    new_values JSONB,
    timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 17. Messages
CREATE TABLE IF NOT EXISTS gpi.messages (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    from_user_id TEXT NOT NULL, -- external_id
    to_user_id TEXT NOT NULL,   -- external_id
    message TEXT NOT NULL,
    is_read BOOLEAN DEFAULT FALSE,
    read_at TIMESTAMP WITH TIME ZONE,
    is_archived BOOLEAN DEFAULT FALSE,
    is_deleted_by_recipient BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 18. Geometry Types
CREATE TABLE IF NOT EXISTS gpi.geometry_types (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    efficiency_loss DECIMAL DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE (organization_id, name)
);

-- 19. Stored Files
CREATE TABLE IF NOT EXISTS gpi.stored_files (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    organization_id UUID REFERENCES gpi.organizations(id) ON DELETE CASCADE,
    filename TEXT NOT NULL,
    original_name TEXT,
    mimetype TEXT,
    size INTEGER,
    path TEXT,
    category TEXT,
    reference_id TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Indexes
CREATE INDEX IF NOT EXISTS idx_projects_org ON gpi.projects(organization_id);
CREATE INDEX IF NOT EXISTS idx_parts_project ON gpi.parts(project_id);
CREATE INDEX IF NOT EXISTS idx_schemes_project ON gpi.painting_schemes(project_id);
CREATE INDEX IF NOT EXISTS idx_records_project ON gpi.application_records(project_id);
CREATE INDEX IF NOT EXISTS idx_inspections_project ON gpi.inspections(project_id);
CREATE INDEX IF NOT EXISTS idx_stock_org ON gpi.stock_items(organization_id);
CREATE INDEX IF NOT EXISTS idx_notifications_recipient ON gpi.notifications(recipient_id);
CREATE INDEX IF NOT EXISTS idx_messages_to ON gpi.messages(to_user_id, is_read);
CREATE INDEX IF NOT EXISTS idx_geometry_types_org ON gpi.geometry_types(organization_id);
