-- =============================================================================
-- SCHEMA COMPLETO PER CATALOGO CELEBRITÀ
-- VERSIONE: 4.2
-- DESCRIZIONE: Schema base con espansione della taglia del reggiseno e
--              aggiunta della cronologia degli interventi estetici.
-- DATABASE: PostgreSQL
-- =============================================================================

-- PREPARAZIONE: Elimina vecchie strutture per una creazione pulita
DROP TABLE IF EXISTS
    cosmetic_surgeries,
    activity_periods,
    celebrity_aliases,
    tattoos,
    video_performers,
    videos,
    celebrity_studios,
    studios,
    external_links,
    images,
    social_media_accounts,
    celebrity_professions,
    professions,
    celebrities CASCADE;

DROP TYPE IF EXISTS GENDER_TYPE;
DROP TYPE IF EXISTS SHOE_SYSTEM_TYPE;
DROP TYPE IF EXISTS BRA_SYSTEM_TYPE;
DROP TYPE IF EXISTS SURGERY_TYPE;

-- =============================================================================
-- DEFINIZIONE DEI TIPI PERSONALIZZATI (ENUMs)
-- =============================================================================

CREATE TYPE GENDER_TYPE AS ENUM ('male', 'female', 'other');
CREATE TYPE SHOE_SYSTEM_TYPE AS ENUM ('EU', 'US', 'UK');
CREATE TYPE BRA_SYSTEM_TYPE AS ENUM ('US', 'UK', 'EU', 'FR', 'AU', 'IT', 'JP');
CREATE TYPE SURGERY_TYPE AS ENUM (
    'breast_reduction', 
    'breast_augmentation', 
    'breast_lift',
    'rhinoplasty', 
    'other'
);

-- =============================================================================
-- TABELLE PRINCIPALI
-- =============================================================================

-- Tabella centrale che contiene tutte le informazioni anagrafiche e fisiche
-- I dati fisici (es. taglia reggiseno) rappresentano lo STATO ATTUALE della celebrità.
CREATE TABLE celebrities (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL UNIQUE,
    gender GENDER_TYPE NOT NULL,
    birth_date DATE,
    birth_place TEXT,
    nationality TEXT,
    ethnicity TEXT,
    sexuality TEXT,
    
    -- Dati fisici (Misure standardizzate in unità metriche per coerenza)
    hair_color TEXT,
    eye_color TEXT,
    height_cm INT CHECK (height_cm > 0),
    weight_kg INT CHECK (weight_kg > 0),
    body_type TEXT,
    
    -- Misure femminili (in cm). NULL se non applicabile.
    bust_cm INT CHECK (bust_cm > 0),
    waist_cm INT CHECK (waist_cm > 0),
    hips_cm INT CHECK (hips_cm > 0),
    
    -- Misure maschili (in cm). NULL se non applicabile.
    chest_circumference_cm INT CHECK (chest_circumference_cm > 0),
    
    -- Campi strutturati per la taglia del reggiseno (stato attuale)
    bra_band_size INT CHECK (bra_band_size > 0), -- Es: 34 (per US/UK) o 75 (per EU)
    bra_cup_size TEXT,                           -- Es: 'C', 'DD', 'E'
    bra_size_system BRA_SYSTEM_TYPE,             -- Sistema di riferimento (US, EU, UK, etc.)
    
    boobs_are_natural BOOLEAN,
    shoe_size DECIMAL(4, 1),
    shoe_size_system SHOE_SYSTEM_TYPE,
    
    -- Dati biografici
    biography TEXT,
    
    -- Metadati e relazioni
    official_website TEXT,
    profile_image_id INT, -- Riferimento all'immagine del profilo (vedi tabella images)
    
    -- Timestamp per tracciamento
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Tabella per i tatuaggi (Relazione 1-a-Molti con celebrities)
CREATE TABLE tattoos (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    description TEXT NOT NULL,
    body_location TEXT
);

-- Tabella per gli alias (Relazione 1-a-Molti con celebrities)
CREATE TABLE celebrity_aliases (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    alias_name TEXT NOT NULL,
    UNIQUE(celebrity_id, alias_name)
);

-- Tabella per i periodi di attività (Relazione 1-a-Molti con celebrities)
CREATE TABLE activity_periods (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    start_year INT NOT NULL CHECK (start_year > 1900 AND start_year < 2100),
    end_year INT CHECK (end_year >= start_year), -- Può essere NULL se ancora in attività per questo periodo
    notes TEXT -- Es. "Carriera principale", "Ritorno sulle scene"
);

-- =============================================================================
-- TABELLE DI "LOOKUP" E DI COLLEGAMENTO (MOLTI-A-MOLTI)
-- =============================================================================

CREATE TABLE professions (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL UNIQUE
);
CREATE TABLE celebrity_professions (
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    profession_id INT NOT NULL REFERENCES professions(id) ON DELETE CASCADE,
    PRIMARY KEY (celebrity_id, profession_id)
);

CREATE TABLE studios (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL UNIQUE
);
CREATE TABLE celebrity_studios (
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    studio_id INT NOT NULL REFERENCES studios(id) ON DELETE CASCADE,
    PRIMARY KEY (celebrity_id, studio_id)
);

CREATE TABLE videos (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    release_date DATE,
    studio_id INT REFERENCES studios(id) ON DELETE SET NULL,
    description TEXT,
    url_preview TEXT
);
CREATE TABLE video_performers (
    video_id INT NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    PRIMARY KEY (video_id, celebrity_id)
);

-- =============================================================================
-- TABELLE SATELLITE (Informazioni aggiuntive)
-- =============================================================================

-- Tabella per tracciare la cronologia degli interventi estetici
CREATE TABLE cosmetic_surgeries (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    surgery_type SURGERY_TYPE NOT NULL,
    surgery_date DATE, -- Data (anche approssimativa) dell'intervento
    
    -- Campi specifici per interventi al seno (saranno NULL per altri tipi di intervento)
    -- Rappresentano la taglia RISULTANTE dall'intervento
    new_bra_band_size INT CHECK (new_bra_band_size > 0),
    new_bra_cup_size TEXT,
    new_bra_size_system BRA_SYSTEM_TYPE,
    
    -- Campi generici
    notes TEXT, -- Dettagli aggiuntivi (es. nome del medico, clinica, motivo dell'intervento)
    
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE social_media_accounts (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    platform TEXT NOT NULL,
    url TEXT NOT NULL UNIQUE,
    follower_count BIGINT,
    last_checked_date DATE
);

CREATE TABLE images (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    file_path TEXT NOT NULL,
    caption TEXT,
    uploaded_at TIMESTAMPTZ DEFAULT NOW()
);

-- Aggiunta del vincolo di chiave esterna per la foto profilo
-- Deve essere aggiunto dopo la creazione della tabella 'images'
ALTER TABLE celebrities
ADD CONSTRAINT fk_profile_image
FOREIGN KEY (profile_image_id) REFERENCES images(id) ON DELETE SET NULL;

CREATE TABLE external_links (
    id SERIAL PRIMARY KEY,
    celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE,
    url TEXT NOT NULL,
    title TEXT,
    source_website TEXT,
    publication_date DATE
);

-- =============================================================================
-- CREAZIONE DEGLI INDICI PER MIGLIORARE LE PERFORMANCE
-- =============================================================================

-- Indici sulla tabella principale
CREATE INDEX idx_celebrities_name ON celebrities(name);
CREATE INDEX idx_celebrities_gender ON celebrities(gender);

-- Indici sulle chiavi esterne per accelerare i JOIN
CREATE INDEX idx_cosmetic_surgeries_celebrity_id ON cosmetic_surgeries(celebrity_id);
CREATE INDEX idx_tattoos_celebrity_id ON tattoos(celebrity_id);
CREATE INDEX idx_celebrity_aliases_celebrity_id ON celebrity_aliases(celebrity_id);
CREATE INDEX idx_celebrity_aliases_name ON celebrity_aliases(alias_name); -- Utile per cercare un alias
CREATE INDEX idx_activity_periods_celebrity_id ON activity_periods(celebrity_id);
CREATE INDEX idx_celebrity_professions_celebrity_id ON celebrity_professions(celebrity_id);
CREATE INDEX idx_celebrity_studios_celebrity_id ON celebrity_studios(celebrity_id);
CREATE INDEX idx_video_performers_celebrity_id ON video_performers(celebrity_id);
CREATE INDEX idx_social_media_celebrity_id ON social_media_accounts(celebrity_id);
CREATE INDEX idx_images_celebrity_id ON images(celebrity_id);
CREATE INDEX idx_external_links_celebrity_id ON external_links(celebrity_id);

-- =============================================================================
-- FINE DELLO SCRIPT
-- =============================================================================