-- Migration 005: Fahrzeugverwaltung (Vehicle Fleet Management)
-- Depends on: 001_create_users_table.sql (uuid-ossp extension, users table)

-- ============================================================
-- TABLE: fahrzeuge
-- ============================================================
CREATE TABLE IF NOT EXISTS fahrzeuge (
    id                  UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    bezeichnung         VARCHAR(100) NOT NULL,                  -- e.g. "LF 20/16", "HLF 10"
    kurzname            VARCHAR(20),                            -- e.g. "LF1", "HLF2"
    amtliches_kennzeichen VARCHAR(20) UNIQUE,                  -- e.g. "WN-FW 1"
    fahrgestellnummer   VARCHAR(50),                           -- VIN
    baujahr             INTEGER CHECK (baujahr >= 1950 AND baujahr <= 2100),
    hersteller          VARCHAR(100),                          -- e.g. "MAN", "Mercedes-Benz", "Rosenbauer"
    typ_schluessel      VARCHAR(30),                           -- DIN 14502 code, e.g. "LF 20/16"
    besatzung_soll      VARCHAR(10),                           -- crew config e.g. "1/8", "1/5"
    status              VARCHAR(40) NOT NULL DEFAULT 'einsatzbereit'
                            CHECK (status IN (
                                'einsatzbereit',
                                'ausser_dienst_wartung',
                                'ausser_dienst_schaden',
                                'in_lehrgang'
                            )),
    status_bemerkung    TEXT,
    standort            VARCHAR(100) NOT NULL DEFAULT 'Feuerwehrhaus',
    bild_url            VARCHAR(500),
    created_at          TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at          TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_fahrzeuge_status ON fahrzeuge(status);
CREATE INDEX IF NOT EXISTS idx_fahrzeuge_kennzeichen ON fahrzeuge(amtliches_kennzeichen);

-- Auto-update updated_at (reuses function from migration 001)
CREATE TRIGGER update_fahrzeuge_updated_at
    BEFORE UPDATE ON fahrzeuge
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();


-- ============================================================
-- TABLE: fahrzeug_pruefungen
-- Stores both upcoming scheduled inspections AND completed ones.
-- A row with durchgefuehrt_am = NULL is an open/scheduled inspection.
-- ============================================================
CREATE TABLE IF NOT EXISTS fahrzeug_pruefungen (
    id                  UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    fahrzeug_id         UUID NOT NULL REFERENCES fahrzeuge(id) ON DELETE CASCADE,
    pruefung_art        VARCHAR(30) NOT NULL
                            CHECK (pruefung_art IN (
                                'HU',           -- Hauptuntersuchung (TÜV), 24-month interval
                                'AU',           -- Abgasuntersuchung, 12-month interval
                                'UVV',          -- Unfallverhütungsvorschrift BGV D29, 12-month
                                'Leiter',       -- Leiternprüfung (DLK), 12-month
                                'Kran',         -- Kranprüfung, 12-month
                                'Seilwinde',    -- Seilwindenprüfung, 12-month
                                'Sonstiges'
                            )),
    -- faellig_am: the deadline by which this inspection must be completed
    faellig_am          DATE NOT NULL,
    -- durchgefuehrt_am: NULL = not yet done; set when inspection is completed
    durchgefuehrt_am    DATE,
    ergebnis            VARCHAR(30)
                            CHECK (ergebnis IS NULL OR ergebnis IN (
                                'bestanden',
                                'bestanden_mit_maengeln',
                                'nicht_bestanden',
                                'ausstehend'
                            )),
    -- naechste_faelligkeit: auto-calculated next due date after completion
    naechste_faelligkeit DATE,
    pruefende_stelle    VARCHAR(150),              -- e.g. "TÜV Süd Stuttgart", "DEKRA"
    kosten              DECIMAL(8,2),
    dokument_url        VARCHAR(500),
    bemerkung           TEXT,
    erfasst_von         UUID REFERENCES users(id) ON DELETE SET NULL,
    created_at          TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_pruefungen_fahrzeug_id ON fahrzeug_pruefungen(fahrzeug_id);
CREATE INDEX IF NOT EXISTS idx_pruefungen_faellig_am ON fahrzeug_pruefungen(faellig_am);
CREATE INDEX IF NOT EXISTS idx_pruefungen_art ON fahrzeug_pruefungen(pruefung_art);
-- Composite index for the "latest per type" query pattern
CREATE INDEX IF NOT EXISTS idx_pruefungen_fahrzeug_art_faellig
    ON fahrzeug_pruefungen(fahrzeug_id, pruefung_art, faellig_am DESC);


-- ============================================================
-- TABLE: fahrzeug_wartungslog
-- Service/maintenance log entries (fuel, repairs, tyres, etc.)
-- ============================================================
CREATE TABLE IF NOT EXISTS fahrzeug_wartungslog (
    id                  UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    fahrzeug_id         UUID NOT NULL REFERENCES fahrzeuge(id) ON DELETE CASCADE,
    datum               DATE NOT NULL,
    art                 VARCHAR(30)
                            CHECK (art IS NULL OR art IN (
                                'Inspektion',
                                'Reparatur',
                                'Kraftstoff',
                                'Reifenwechsel',
                                'Hauptuntersuchung',
                                'Reinigung',
                                'Sonstiges'
                            )),
    beschreibung        TEXT NOT NULL,
    km_stand            INTEGER CHECK (km_stand >= 0),
    kraftstoff_liter    DECIMAL(6,2) CHECK (kraftstoff_liter >= 0),
    kosten              DECIMAL(8,2) CHECK (kosten >= 0),
    externe_werkstatt   VARCHAR(150),
    erfasst_von         UUID REFERENCES users(id) ON DELETE SET NULL,
    created_at          TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_wartungslog_fahrzeug_id ON fahrzeug_wartungslog(fahrzeug_id);
CREATE INDEX IF NOT EXISTS idx_wartungslog_datum ON fahrzeug_wartungslog(datum DESC);


-- ============================================================
-- VIEW: fahrzeuge_mit_pruefstatus
-- For each vehicle, joins its LATEST scheduled pruefung per art
-- and computes tage_bis_faelligkeit (negative = overdue).
-- The dashboard alert panel and fleet overview query this view.
-- ============================================================
CREATE OR REPLACE VIEW fahrzeuge_mit_pruefstatus AS
WITH latest_pruefungen AS (
    -- For each (fahrzeug, pruefung_art) pair, pick the row with the
    -- latest faellig_am that is NOT yet completed (durchgefuehrt_am IS NULL),
    -- OR if all are completed, the one with the highest naechste_faelligkeit.
    SELECT DISTINCT ON (fahrzeug_id, pruefung_art)
        fahrzeug_id,
        pruefung_art,
        id              AS pruefung_id,
        faellig_am,
        durchgefuehrt_am,
        ergebnis,
        naechste_faelligkeit,
        pruefende_stelle,
        CURRENT_DATE - faellig_am::date AS tage_ueberfaellig,
        faellig_am::date - CURRENT_DATE AS tage_bis_faelligkeit
    FROM fahrzeug_pruefungen
    ORDER BY
        fahrzeug_id,
        pruefung_art,
        -- Open inspections (nicht durchgeführt) first, then most recent
        (durchgefuehrt_am IS NULL) DESC,
        faellig_am DESC
)
SELECT
    f.id,
    f.bezeichnung,
    f.kurzname,
    f.amtliches_kennzeichen,
    f.fahrgestellnummer,
    f.baujahr,
    f.hersteller,
    f.typ_schluessel,
    f.besatzung_soll,
    f.status,
    f.status_bemerkung,
    f.standort,
    f.bild_url,
    f.created_at,
    f.updated_at,
    -- HU
    hu.pruefung_id   AS hu_pruefung_id,
    hu.faellig_am    AS hu_faellig_am,
    hu.tage_bis_faelligkeit AS hu_tage_bis_faelligkeit,
    hu.ergebnis      AS hu_ergebnis,
    -- AU
    au.pruefung_id   AS au_pruefung_id,
    au.faellig_am    AS au_faellig_am,
    au.tage_bis_faelligkeit AS au_tage_bis_faelligkeit,
    au.ergebnis      AS au_ergebnis,
    -- UVV
    uvv.pruefung_id  AS uvv_pruefung_id,
    uvv.faellig_am   AS uvv_faellig_am,
    uvv.tage_bis_faelligkeit AS uvv_tage_bis_faelligkeit,
    uvv.ergebnis     AS uvv_ergebnis,
    -- Leiter (DLK only)
    leiter.pruefung_id AS leiter_pruefung_id,
    leiter.faellig_am  AS leiter_faellig_am,
    leiter.tage_bis_faelligkeit AS leiter_tage_bis_faelligkeit,
    leiter.ergebnis    AS leiter_ergebnis,
    -- Overall worst tage_bis_faelligkeit across all active inspections
    LEAST(
        hu.tage_bis_faelligkeit,
        au.tage_bis_faelligkeit,
        uvv.tage_bis_faelligkeit,
        leiter.tage_bis_faelligkeit
    ) AS naechste_pruefung_tage
FROM
    fahrzeuge f
    LEFT JOIN latest_pruefungen hu     ON hu.fahrzeug_id = f.id  AND hu.pruefung_art = 'HU'
    LEFT JOIN latest_pruefungen au     ON au.fahrzeug_id = f.id  AND au.pruefung_art = 'AU'
    LEFT JOIN latest_pruefungen uvv    ON uvv.fahrzeug_id = f.id AND uvv.pruefung_art = 'UVV'
    LEFT JOIN latest_pruefungen leiter ON leiter.fahrzeug_id = f.id AND leiter.pruefung_art = 'Leiter';


-- ============================================================
-- SEED DATA: 3 typical German Feuerwehr vehicles
-- ============================================================
DO $$
DECLARE
    v_lf10_id  UUID := uuid_generate_v4();
    v_hlf20_id UUID := uuid_generate_v4();
    v_mtf_id   UUID := uuid_generate_v4();
BEGIN
    -- Only insert if no vehicles exist yet (idempotent seed)
    IF (SELECT COUNT(*) FROM fahrzeuge) = 0 THEN

        -- 1) LF 10 – Standard Löschgruppenfahrzeug
        INSERT INTO fahrzeuge (
            id, bezeichnung, kurzname, amtliches_kennzeichen,
            fahrgestellnummer, baujahr, hersteller, typ_schluessel,
            besatzung_soll, status, standort
        ) VALUES (
            v_lf10_id,
            'LF 10',
            'LF 1',
            'WN-FW 1',
            'WDB9634031L123456',
            2018,
            'Mercedes-Benz Atego',
            'LF 10',
            '1/8',
            'einsatzbereit',
            'Feuerwehrhaus'
        );

        -- LF 10 inspections
        INSERT INTO fahrzeug_pruefungen (fahrzeug_id, pruefung_art, faellig_am, durchgefuehrt_am, ergebnis, naechste_faelligkeit, pruefende_stelle) VALUES
            (v_lf10_id, 'HU',  '2026-03-15', NULL,         'ausstehend', NULL,         'TÜV Süd Stuttgart'),
            (v_lf10_id, 'AU',  '2026-04-01', NULL,         'ausstehend', NULL,         'TÜV Süd Stuttgart'),
            (v_lf10_id, 'UVV', '2025-11-30', '2025-11-28', 'bestanden',  '2026-11-28', 'DGUV Prüfer Rems');

        -- LF 10 maintenance log
        INSERT INTO fahrzeug_wartungslog (fahrzeug_id, datum, art, beschreibung, km_stand, kraftstoff_liter, kosten) VALUES
            (v_lf10_id, '2025-11-28', 'Inspektion',  'Jahresinspektion nach Herstellervorgabe, Öl- und Filterwechsel, Bremsenprüfung', 48320, NULL, 420.00),
            (v_lf10_id, '2025-10-15', 'Kraftstoff',  'Betankung nach Einsatz Feuerwehr Rems', 48150, 85.4, 145.18),
            (v_lf10_id, '2025-09-01', 'Reifenwechsel','Sommerreifen auf Winterreifen gewechselt, alle 4 Reifen erneuert (Continental)', 47800, NULL, 980.00);

        -- 2) HLF 20/16 – Hilfeleistungslöschgruppenfahrzeug (flagship)
        INSERT INTO fahrzeuge (
            id, bezeichnung, kurzname, amtliches_kennzeichen,
            fahrgestellnummer, baujahr, hersteller, typ_schluessel,
            besatzung_soll, status, standort
        ) VALUES (
            v_hlf20_id,
            'HLF 20/16',
            'HLF 1',
            'WN-FW 2',
            'WMAN29ZZ3LM654321',
            2020,
            'MAN TGM / Rosenbauer',
            'HLF 20/16',
            '1/8',
            'einsatzbereit',
            'Feuerwehrhaus'
        );

        -- HLF 20 inspections — all current
        INSERT INTO fahrzeug_pruefungen (fahrzeug_id, pruefung_art, faellig_am, durchgefuehrt_am, ergebnis, naechste_faelligkeit, pruefende_stelle) VALUES
            (v_hlf20_id, 'HU',  '2026-08-20', NULL,         'ausstehend', NULL,         'DEKRA Esslingen'),
            (v_hlf20_id, 'AU',  '2026-02-01', '2026-01-28', 'bestanden',  '2027-01-28', 'DEKRA Esslingen'),
            (v_hlf20_id, 'UVV', '2026-01-15', '2026-01-14', 'bestanden',  '2027-01-14', 'DGUV Prüfer Rems');

        -- HLF 20 maintenance log
        INSERT INTO fahrzeug_wartungslog (fahrzeug_id, datum, art, beschreibung, km_stand, kraftstoff_liter, kosten) VALUES
            (v_hlf20_id, '2026-01-28', 'Hauptuntersuchung', 'AU bestanden ohne Mängel bei DEKRA Esslingen', 22450, NULL, 185.00),
            (v_hlf20_id, '2026-01-14', 'Inspektion',        'UVV-Prüfung bestanden, Licht und Bremsen geprüft', 22430, NULL, 0.00),
            (v_hlf20_id, '2025-12-10', 'Kraftstoff',        'Betankung nach Übung', 22300, 120.0, 204.00),
            (v_hlf20_id, '2025-10-05', 'Reparatur',         'Hydraulikpumpe für Rettungssatz getauscht', 21980, NULL, 2340.00);

        -- 3) MTF – Mannschaftstransportfahrzeug
        INSERT INTO fahrzeuge (
            id, bezeichnung, kurzname, amtliches_kennzeichen,
            fahrgestellnummer, baujahr, hersteller, typ_schluessel,
            besatzung_soll, status, status_bemerkung, standort
        ) VALUES (
            v_mtf_id,
            'MTF',
            'MTF 1',
            'WN-FW 5',
            'WDB9066371S789012',
            2015,
            'Mercedes-Benz Sprinter',
            'MTF',
            '1/8',
            'ausser_dienst_wartung',
            'Geplante Inspektion: Zahnriemenwechsel 60.000 km fällig',
            'Feuerwehrhaus'
        );

        -- MTF inspections — HU overdue (safety-critical test data)
        INSERT INTO fahrzeug_pruefungen (fahrzeug_id, pruefung_art, faellig_am, durchgefuehrt_am, ergebnis, naechste_faelligkeit, pruefende_stelle) VALUES
            (v_mtf_id, 'HU',  '2026-01-31', NULL,         'ausstehend', NULL,         'TÜV Süd Stuttgart'),
            (v_mtf_id, 'AU',  '2025-06-15', '2025-06-12', 'bestanden',  '2026-06-12', 'TÜV Süd Stuttgart'),
            (v_mtf_id, 'UVV', '2025-12-01', '2025-11-30', 'bestanden_mit_maengeln', '2026-11-30', 'DGUV Prüfer Rems');

        -- MTF maintenance log
        INSERT INTO fahrzeug_wartungslog (fahrzeug_id, datum, art, beschreibung, km_stand, kraftstoff_liter, kosten) VALUES
            (v_mtf_id, '2025-11-30', 'Inspektion',  'UVV-Prüfung: kleiner Mangel Innenbeleuchtung, nachgebessert', 58920, NULL, 0.00),
            (v_mtf_id, '2025-11-01', 'Kraftstoff',  'Betankung regulär', 58700, 65.0, 110.50),
            (v_mtf_id, '2025-09-20', 'Reparatur',   'Heckleuchte links defekt, Glühbirne getauscht', 58400, NULL, 12.50);

    END IF;
END
$$;

-- ---------------------------------------------------------------------------
-- Cross-migration FK: add fahrzeug_id FK to einsatz_fahrzeuge (created in 004)
-- This runs only if einsatz_fahrzeuge exists but the FK is not yet present.
-- Handles the case where 004 ran before 005 and deferred the FK creation.
-- ---------------------------------------------------------------------------
DO $$
BEGIN
    IF EXISTS (
        SELECT 1 FROM information_schema.tables
        WHERE table_schema = 'public' AND table_name = 'einsatz_fahrzeuge'
    )
    AND NOT EXISTS (
        SELECT 1 FROM information_schema.table_constraints
        WHERE table_name = 'einsatz_fahrzeuge'
          AND constraint_name = 'fk_ef_fahrzeug'
    ) THEN
        ALTER TABLE einsatz_fahrzeuge
            ADD CONSTRAINT fk_ef_fahrzeug
            FOREIGN KEY (fahrzeug_id) REFERENCES fahrzeuge(id) ON DELETE CASCADE;
        RAISE NOTICE 'Added fk_ef_fahrzeug FK on einsatz_fahrzeuge';
    END IF;
END $$;
