-- Ferrero Asset Tracking Database Schema
-- Phase 1: Asset Ingestion

-- Create extension for UUID generation (optional, for future use)
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Master Assets Table
-- Stores master assets ingested from OpenText DAM
CREATE TABLE master_assets (
    id SERIAL PRIMARY KEY,
    tracking_id VARCHAR(6) UNIQUE NOT NULL,
    opentext_id VARCHAR(255) NOT NULL,
    original_filename VARCHAR(500) NOT NULL,
    file_extension VARCHAR(20),
    upload_directory VARCHAR(1000),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    -- Metadata fields
    brand_code VARCHAR(5),
    brand_name VARCHAR(255),
    country_code VARCHAR(2),
    country_name VARCHAR(255),
    language_code VARCHAR(3),
    language_name VARCHAR(100),
    subject_title VARCHAR(255),
    asset_type VARCHAR(3),
    asset_type_name VARCHAR(255),
    duration_seconds INTEGER,
    aspect_ratio VARCHAR(10),

    -- Additional metadata
    file_size_bytes BIGINT,
    mime_type VARCHAR(100),
    width_px INTEGER,
    height_px INTEGER,

    -- Tags and categories
    tags TEXT[], -- PostgreSQL array for tags
    categories TEXT[],
    description TEXT,

    -- Status tracking
    status VARCHAR(50) DEFAULT 'active',
    is_deleted BOOLEAN DEFAULT FALSE,
    deleted_at TIMESTAMP,

    -- Audit fields
    ingested_by VARCHAR(255),
    ingested_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Derivative Assets Table
-- Tracks derivative assets linked to master assets
CREATE TABLE derivative_assets (
    id SERIAL PRIMARY KEY,
    tracking_id VARCHAR(6) NOT NULL,
    derivative_filename VARCHAR(500) NOT NULL,
    file_extension VARCHAR(20),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    -- Link to master asset
    master_asset_id INTEGER REFERENCES master_assets(id) ON DELETE CASCADE,

    -- Override metadata (language and asset type can differ from master)
    language_code VARCHAR(3),
    language_name VARCHAR(100),
    asset_type VARCHAR(3),
    asset_type_name VARCHAR(255),
    duration_seconds INTEGER,
    aspect_ratio VARCHAR(10),

    -- Additional derivative info
    omg_job_number VARCHAR(10),
    spot_version VARCHAR(10),
    has_master_flag BOOLEAN DEFAULT FALSE,

    -- Status
    status VARCHAR(50) DEFAULT 'active',
    uploaded_at TIMESTAMP,

    -- Audit fields
    created_by VARCHAR(255),

    FOREIGN KEY (tracking_id) REFERENCES master_assets(tracking_id)
);

-- Asset Lifecycle Events Table
-- Tracks all events in asset lifecycle
CREATE TABLE asset_lifecycle_events (
    id SERIAL PRIMARY KEY,
    tracking_id VARCHAR(6) NOT NULL,
    event_type VARCHAR(50) NOT NULL, -- 'ingested', 'derivative_created', 'uploaded', 'deleted', etc.
    event_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    event_data JSONB, -- Flexible field for event-specific data
    user_id VARCHAR(255),
    ip_address INET,
    user_agent TEXT
);

-- Tracking ID Generation Log
-- Keeps track of all generated tracking IDs to prevent collisions
CREATE TABLE tracking_id_log (
    id SERIAL PRIMARY KEY,
    tracking_id VARCHAR(6) UNIQUE NOT NULL,
    generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    assigned_to_asset BOOLEAN DEFAULT FALSE,
    assigned_at TIMESTAMP
);

-- Indexes for performance
CREATE INDEX idx_master_assets_tracking_id ON master_assets(tracking_id);
CREATE INDEX idx_master_assets_opentext_id ON master_assets(opentext_id);
CREATE INDEX idx_master_assets_brand_code ON master_assets(brand_code);
CREATE INDEX idx_master_assets_status ON master_assets(status);
CREATE INDEX idx_master_assets_created_at ON master_assets(created_at);

CREATE INDEX idx_derivative_assets_tracking_id ON derivative_assets(tracking_id);
CREATE INDEX idx_derivative_assets_master_id ON derivative_assets(master_asset_id);
CREATE INDEX idx_derivative_assets_omg_job ON derivative_assets(omg_job_number);

CREATE INDEX idx_lifecycle_events_tracking_id ON asset_lifecycle_events(tracking_id);
CREATE INDEX idx_lifecycle_events_type ON asset_lifecycle_events(event_type);
CREATE INDEX idx_lifecycle_events_timestamp ON asset_lifecycle_events(event_timestamp);

CREATE INDEX idx_tracking_log_id ON tracking_id_log(tracking_id);

-- Function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Trigger for master_assets updated_at
CREATE TRIGGER update_master_assets_updated_at
    BEFORE UPDATE ON master_assets
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- Function to log lifecycle events automatically
CREATE OR REPLACE FUNCTION log_master_asset_event()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        INSERT INTO asset_lifecycle_events (tracking_id, event_type, event_data)
        VALUES (NEW.tracking_id, 'master_ingested',
                jsonb_build_object(
                    'opentext_id', NEW.opentext_id,
                    'filename', NEW.original_filename,
                    'brand_code', NEW.brand_code
                ));
    ELSIF TG_OP = 'UPDATE' AND OLD.status != NEW.status THEN
        INSERT INTO asset_lifecycle_events (tracking_id, event_type, event_data)
        VALUES (NEW.tracking_id, 'status_changed',
                jsonb_build_object(
                    'old_status', OLD.status,
                    'new_status', NEW.status
                ));
    ELSIF TG_OP = 'DELETE' THEN
        INSERT INTO asset_lifecycle_events (tracking_id, event_type, event_data)
        VALUES (OLD.tracking_id, 'master_deleted',
                jsonb_build_object(
                    'opentext_id', OLD.opentext_id,
                    'filename', OLD.original_filename
                ));
    END IF;
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Trigger for automatic lifecycle logging
CREATE TRIGGER log_master_asset_changes
    AFTER INSERT OR UPDATE OR DELETE ON master_assets
    FOR EACH ROW
    EXECUTE FUNCTION log_master_asset_event();

-- Function to log derivative asset events
CREATE OR REPLACE FUNCTION log_derivative_asset_event()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        INSERT INTO asset_lifecycle_events (tracking_id, event_type, event_data)
        VALUES (NEW.tracking_id, 'derivative_created',
                jsonb_build_object(
                    'filename', NEW.derivative_filename,
                    'omg_job_number', NEW.omg_job_number,
                    'master_asset_id', NEW.master_asset_id
                ));
    ELSIF TG_OP = 'UPDATE' AND NEW.uploaded_at IS NOT NULL AND OLD.uploaded_at IS NULL THEN
        INSERT INTO asset_lifecycle_events (tracking_id, event_type, event_data)
        VALUES (NEW.tracking_id, 'derivative_uploaded',
                jsonb_build_object(
                    'filename', NEW.derivative_filename,
                    'uploaded_at', NEW.uploaded_at
                ));
    END IF;
    RETURN NEW;
END;
$$ language 'plpgsql';

-- Trigger for derivative asset lifecycle logging
CREATE TRIGGER log_derivative_asset_changes
    AFTER INSERT OR UPDATE ON derivative_assets
    FOR EACH ROW
    EXECUTE FUNCTION log_derivative_asset_event();

-- View for complete asset information
CREATE VIEW v_master_assets_complete AS
SELECT
    ma.id,
    ma.tracking_id,
    ma.opentext_id,
    ma.original_filename,
    ma.file_extension,
    ma.original_filename || ma.file_extension as full_filename,
    ma.brand_code,
    ma.brand_name,
    ma.country_code,
    ma.country_name,
    ma.language_code,
    ma.language_name,
    ma.subject_title,
    ma.asset_type,
    ma.asset_type_name,
    ma.duration_seconds,
    ma.aspect_ratio,
    ma.file_size_bytes,
    ma.mime_type,
    ma.width_px,
    ma.height_px,
    ma.tags,
    ma.categories,
    ma.description,
    ma.status,
    ma.created_at,
    ma.updated_at,
    ma.ingested_by,
    COUNT(DISTINCT da.id) as derivative_count
FROM master_assets ma
LEFT JOIN derivative_assets da ON ma.id = da.master_asset_id
WHERE ma.is_deleted = FALSE
GROUP BY ma.id;

-- View for derivative assets with master info
CREATE VIEW v_derivatives_with_master AS
SELECT
    da.id as derivative_id,
    da.derivative_filename,
    da.omg_job_number,
    da.tracking_id,
    ma.opentext_id,
    ma.original_filename as master_filename,
    ma.brand_code,
    ma.brand_name,
    da.language_code as derivative_language_code,
    da.language_name as derivative_language_name,
    ma.language_code as master_language_code,
    ma.language_name as master_language_name,
    da.asset_type as derivative_asset_type,
    ma.asset_type as master_asset_type,
    da.created_at as derivative_created_at,
    da.uploaded_at as derivative_uploaded_at,
    ma.created_at as master_created_at
FROM derivative_assets da
JOIN master_assets ma ON da.master_asset_id = ma.id
WHERE ma.is_deleted = FALSE;

-- Comments for documentation
COMMENT ON TABLE master_assets IS 'Master assets ingested from OpenText DAM';
COMMENT ON TABLE derivative_assets IS 'Derivative assets created from master assets';
COMMENT ON TABLE asset_lifecycle_events IS 'Complete audit log of all asset lifecycle events';
COMMENT ON TABLE tracking_id_log IS 'Log of all generated tracking IDs for collision prevention';

COMMENT ON COLUMN master_assets.tracking_id IS '6-character alphanumeric unique identifier';
COMMENT ON COLUMN master_assets.opentext_id IS 'Original ID from OpenText DAM system';
COMMENT ON COLUMN master_assets.upload_directory IS 'File system path where the master asset is stored';
COMMENT ON COLUMN master_assets.tags IS 'Array of tags for categorization';
COMMENT ON COLUMN asset_lifecycle_events.event_data IS 'JSONB field for flexible event-specific data';
