-- Nexus Autoparts — Master Database Schema (PostgreSQL)
-- Adapted from SQLite vehicle_database/sql/schema.sql
-- NO TecDoc data included — tables are empty and ready for manual population.

-- =====================================================
-- VEHICLES
-- =====================================================

CREATE TABLE IF NOT EXISTS brands (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL UNIQUE,
    country TEXT,
    founded_year INTEGER,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS engines (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    displacement_cc REAL,
    cylinders INTEGER,
    fuel_type TEXT CHECK(fuel_type IN ('gasoline', 'diesel', 'electric', 'hybrid', 'other')),
    power_hp INTEGER,
    torque_nm INTEGER,
    engine_code TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS models (
    id SERIAL PRIMARY KEY,
    brand_id INTEGER NOT NULL REFERENCES brands(id),
    name TEXT NOT NULL,
    body_type TEXT CHECK(body_type IN ('sedan', 'hatchback', 'suv', 'truck', 'coupe', 'convertible', 'wagon', 'van', 'other')),
    generation TEXT,
    production_start_year INTEGER,
    production_end_year INTEGER,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(brand_id, name, generation)
);

CREATE TABLE IF NOT EXISTS years (
    id SERIAL PRIMARY KEY,
    year INTEGER NOT NULL UNIQUE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS model_year_engine (
    id SERIAL PRIMARY KEY,
    model_id INTEGER NOT NULL REFERENCES models(id),
    year_id INTEGER NOT NULL REFERENCES years(id),
    engine_id INTEGER NOT NULL REFERENCES engines(id),
    trim_level TEXT,
    drivetrain TEXT CHECK(drivetrain IN ('FWD', 'RWD', 'AWD', '4WD', 'other')),
    transmission TEXT CHECK(transmission IN ('manual', 'automatic', 'CVT', 'other')),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(model_id, year_id, engine_id, trim_level)
);

CREATE INDEX IF NOT EXISTS idx_models_brand ON models(brand_id);
CREATE INDEX IF NOT EXISTS idx_model_year_engine_model ON model_year_engine(model_id);
CREATE INDEX IF NOT EXISTS idx_model_year_engine_year ON model_year_engine(year_id);
CREATE INDEX IF NOT EXISTS idx_model_year_engine_engine ON model_year_engine(engine_id);

-- =====================================================
-- PARTS CATALOG
-- =====================================================

CREATE TABLE IF NOT EXISTS part_categories (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    name_es TEXT,
    parent_id INTEGER REFERENCES part_categories(id),
    slug TEXT UNIQUE,
    icon_name TEXT,
    display_order INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS part_groups (
    id SERIAL PRIMARY KEY,
    category_id INTEGER NOT NULL REFERENCES part_categories(id),
    name TEXT NOT NULL,
    name_es TEXT,
    slug TEXT,
    display_order INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS parts (
    id SERIAL PRIMARY KEY,
    oem_part_number TEXT NOT NULL,
    name TEXT NOT NULL,
    name_es TEXT,
    group_id INTEGER REFERENCES part_groups(id),
    description TEXT,
    description_es TEXT,
    weight_kg REAL,
    material TEXT,
    is_discontinued BOOLEAN DEFAULT FALSE,
    superseded_by_id INTEGER REFERENCES parts(id),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS vehicle_parts (
    id SERIAL PRIMARY KEY,
    model_year_engine_id INTEGER NOT NULL REFERENCES model_year_engine(id),
    part_id INTEGER NOT NULL REFERENCES parts(id),
    quantity_required INTEGER DEFAULT 1,
    position TEXT,
    fitment_notes TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(model_year_engine_id, part_id, position)
);

CREATE INDEX IF NOT EXISTS idx_part_categories_parent ON part_categories(parent_id);
CREATE INDEX IF NOT EXISTS idx_part_categories_slug ON part_categories(slug);
CREATE INDEX IF NOT EXISTS idx_part_groups_category ON part_groups(category_id);
CREATE INDEX IF NOT EXISTS idx_parts_oem ON parts(oem_part_number);
CREATE INDEX IF NOT EXISTS idx_parts_group ON parts(group_id);
CREATE INDEX IF NOT EXISTS idx_vehicle_parts_mye ON vehicle_parts(model_year_engine_id);
CREATE INDEX IF NOT EXISTS idx_vehicle_parts_part ON vehicle_parts(part_id);

-- =====================================================
-- AFTERMARKET & CROSS-REFERENCES
-- =====================================================

CREATE TABLE IF NOT EXISTS manufacturers (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL UNIQUE,
    type TEXT CHECK(type IN ('oem', 'aftermarket', 'remanufactured')),
    quality_tier TEXT CHECK(quality_tier IN ('economy', 'standard', 'premium', 'oem')),
    country TEXT,
    logo_url TEXT,
    website TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS aftermarket_parts (
    id SERIAL PRIMARY KEY,
    oem_part_id INTEGER NOT NULL REFERENCES parts(id),
    manufacturer_id INTEGER NOT NULL REFERENCES manufacturers(id),
    part_number TEXT NOT NULL,
    name TEXT,
    name_es TEXT,
    quality_tier TEXT CHECK(quality_tier IN ('economy', 'standard', 'premium')),
    price_usd REAL,
    warranty_months INTEGER,
    in_stock BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS part_cross_references (
    id SERIAL PRIMARY KEY,
    part_id INTEGER NOT NULL REFERENCES parts(id),
    cross_reference_number TEXT NOT NULL,
    reference_type TEXT CHECK(reference_type IN ('oem_alternate', 'supersession', 'interchange', 'competitor')),
    source TEXT,
    notes TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_aftermarket_oem ON aftermarket_parts(oem_part_id);
CREATE INDEX IF NOT EXISTS idx_aftermarket_manufacturer ON aftermarket_parts(manufacturer_id);
CREATE INDEX IF NOT EXISTS idx_aftermarket_part_number ON aftermarket_parts(part_number);
CREATE INDEX IF NOT EXISTS idx_cross_ref_part ON part_cross_references(part_id);
CREATE INDEX IF NOT EXISTS idx_cross_ref_number ON part_cross_references(cross_reference_number);

-- =====================================================
-- DIAGRAMAS EXPLOSIONADOS
-- =====================================================

CREATE TABLE IF NOT EXISTS diagrams (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    name_es TEXT,
    group_id INTEGER NOT NULL REFERENCES part_groups(id),
    image_path TEXT NOT NULL,
    thumbnail_path TEXT,
    svg_content TEXT,
    width INTEGER,
    height INTEGER,
    display_order INTEGER DEFAULT 0,
    source TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS vehicle_diagrams (
    id SERIAL PRIMARY KEY,
    diagram_id INTEGER NOT NULL REFERENCES diagrams(id),
    model_year_engine_id INTEGER NOT NULL REFERENCES model_year_engine(id),
    notes TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(diagram_id, model_year_engine_id)
);

CREATE TABLE IF NOT EXISTS diagram_hotspots (
    id SERIAL PRIMARY KEY,
    diagram_id INTEGER NOT NULL REFERENCES diagrams(id),
    part_id INTEGER REFERENCES parts(id),
    callout_number INTEGER,
    label TEXT,
    shape TEXT DEFAULT 'rect' CHECK(shape IN ('rect', 'circle', 'poly')),
    coords TEXT NOT NULL,
    color TEXT DEFAULT '#e74c3c',
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_diagrams_group ON diagrams(group_id);
CREATE INDEX IF NOT EXISTS idx_vehicle_diagrams_diagram ON vehicle_diagrams(diagram_id);
CREATE INDEX IF NOT EXISTS idx_vehicle_diagrams_mye ON vehicle_diagrams(model_year_engine_id);
CREATE INDEX IF NOT EXISTS idx_hotspots_diagram ON diagram_hotspots(diagram_id);
CREATE INDEX IF NOT EXISTS idx_hotspots_part ON diagram_hotspots(part_id);

-- =====================================================
-- FULL-TEXT SEARCH (PostgreSQL tsvector)
-- =====================================================

-- Add tsvector column to parts for full-text search
ALTER TABLE parts ADD COLUMN IF NOT EXISTS search_vector tsvector;

-- Create GIN index for fast full-text search
CREATE INDEX IF NOT EXISTS idx_parts_search ON parts USING GIN(search_vector);

-- Update function to populate search_vector
CREATE OR REPLACE FUNCTION parts_search_update() RETURNS trigger AS $$
BEGIN
    NEW.search_vector :=
        setweight(to_tsvector('spanish', COALESCE(NEW.name, '')), 'A') ||
        setweight(to_tsvector('spanish', COALESCE(NEW.name_es, '')), 'A') ||
        setweight(to_tsvector('spanish', COALESCE(NEW.oem_part_number, '')), 'B') ||
        setweight(to_tsvector('spanish', COALESCE(NEW.description, '')), 'C') ||
        setweight(to_tsvector('spanish', COALESCE(NEW.description_es, '')), 'C');
    RETURN NEW;
END
$$ LANGUAGE plpgsql;

-- Trigger to auto-update search_vector
DROP TRIGGER IF EXISTS parts_search_trigger ON parts;
CREATE TRIGGER parts_search_trigger
    BEFORE INSERT OR UPDATE ON parts
    FOR EACH ROW EXECUTE FUNCTION parts_search_update();

-- =====================================================
-- VIN CACHE
-- =====================================================

CREATE TABLE IF NOT EXISTS vin_cache (
    id SERIAL PRIMARY KEY,
    vin TEXT NOT NULL UNIQUE,
    decoded_data TEXT NOT NULL,
    make TEXT,
    model TEXT,
    year INTEGER,
    engine_info TEXT,
    body_class TEXT,
    drive_type TEXT,
    model_year_engine_id INTEGER REFERENCES model_year_engine(id),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    expires_at TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_vin_cache_vin ON vin_cache(vin);
CREATE INDEX IF NOT EXISTS idx_vin_cache_make_model ON vin_cache(make, model, year);
