-- Usunięcie istniejących obiektów

-- Tworzenie tabel
CREATE TABLE ap448380.galeria
(
    idgaleria  INTEGER PRIMARY KEY,
    nazwa      VARCHAR(30) NOT NULL,
    adres      VARCHAR(50) NOT NULL
);

CREATE TABLE ap448380.artysta
(
    idartysta  INTEGER PRIMARY KEY,
    imie       VARCHAR(30) NOT NULL,
    nazwisko   VARCHAR(30) NOT NULL,
    urodzenie  DATE NOT NULL,
    smierc     DATE CHECK (smierc > urodzenie OR smierc IS NULL)
);

CREATE TABLE ap448380.eksponat
(
    ideksponat   INTEGER PRIMARY KEY,
    idartysta    INTEGER REFERENCES ap448380.artysta(idartysta),
    tytul        VARCHAR(50) NOT NULL,
    typ          INTEGER NOT NULL,
    wysokosc     DECIMAL(10, 2) NOT NULL,
    szerokosc    DECIMAL(10, 2) NOT NULL, 
    waga         DECIMAL(10, 2) NOT NULL,
    wypozyczone  BOOLEAN NOT NULL
);

CREATE TABLE ap448380.instytucja
(
    idinstytucja  INTEGER PRIMARY KEY,
    nazwa         VARCHAR(30) NOT NULL,
    miasto        VARCHAR(30) NOT NULL
);

CREATE TABLE ap448380.historia
(
    idhistoria      INTEGER PRIMARY KEY,
    idgaleria       INTEGER REFERENCES ap448380.galeria(idgaleria),
    ideksponat      INTEGER NOT NULL REFERENCES ap448380.eksponat(ideksponat),
    idinstytucja    INTEGER REFERENCES ap448380.instytucja(idinstytucja),
    datarozpoczecia DATE NOT NULL,
    datazakonczenia DATE CHECK (datazakonczenia > datarozpoczecia OR datazakonczenia IS NULL)
);

-- Funkcja dodająca eksponat
CREATE OR REPLACE FUNCTION ap448380.dodajeksponat (
    ideksponat  INTEGER,
    tytul       VARCHAR(50),
    idartysta   INTEGER,
    typ         INTEGER,
    wysokosc    DECIMAL(10, 2),
    szerokosc   DECIMAL(10, 2),
    waga        DECIMAL(10, 2),
    wypozyczone BOOLEAN
)
RETURNS VOID AS $$
BEGIN
    INSERT INTO ap448380.eksponat (
        ideksponat, tytul, idartysta, typ, wysokosc, szerokosc, waga, wypozyczone
    ) VALUES (
        ideksponat, tytul, idartysta, typ, wysokosc, szerokosc, waga, wypozyczone
    );
END;
$$ LANGUAGE plpgsql;

-- Usunięcie starych funkcji i triggerów, jeśli istnieją
DROP FUNCTION IF EXISTS ap448380.sprawdzlimitwypozyczen CASCADE;
DROP FUNCTION IF EXISTS ap448380.aktualizujstatuswypozyczenia CASCADE;
DROP TRIGGER IF EXISTS limit_wypozyczen ON ap448380.historia;
DROP TRIGGER IF EXISTS eksponaty_artysty ON ap448380.historia;
DROP TRIGGER IF EXISTS status_wypozyczenia ON ap448380.historia;

-- Trigger: Sprawdzanie, czy eksponat nie przebywa poza muzeum dłużej niż 30 dni rocznie

CREATE OR REPLACE FUNCTION ap448380.sprawdzlimitwypozyczen()
RETURNS TRIGGER AS $$
DECLARE
    suma_dni INTEGER;
    max_data_zakonczenia DATE;
BEGIN
    -- Sumujemy dni z istniejących rekordów dla danego eksponatu
    SELECT COALESCE(SUM(datazakonczenia - datarozpoczecia), 0)
      INTO suma_dni
      FROM ap448380.historia
      WHERE ideksponat = NEW.ideksponat;

    -- Obliczamy maksymalną dopuszczalną datę zakończenia
    max_data_zakonczenia := NEW.datarozpoczecia + INTERVAL '30 days';

    -- Jeśli nowa data przekroczyłaby limit, ustawiamy na max_data_zakonczenia
    IF (suma_dni + (NEW.datazakonczenia - NEW.datarozpoczecia)) > 30 THEN
        NEW.datazakonczenia := max_data_zakonczenia;
    END IF;
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;


CREATE TRIGGER limit_wypozyczen
BEFORE INSERT OR UPDATE ON ap448380.historia
FOR EACH ROW EXECUTE FUNCTION ap448380.sprawdzlimitwypozyczen();


-- Trigger: Automatyczna aktualizacja statusu wypożyczenia
CREATE OR REPLACE FUNCTION ap448380.aktualizujstatuswypozyczenia()
RETURNS TRIGGER AS $$
BEGIN
    IF NEW.idinstytucja IS NOT NULL THEN
        UPDATE ap448380.eksponat SET wypozyczone = TRUE WHERE ideksponat = NEW.ideksponat;
    ELSE
        UPDATE ap448380.eksponat SET wypozyczone = FALSE WHERE ideksponat = NEW.ideksponat;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;


CREATE TRIGGER status_wypozyczenia
AFTER INSERT OR UPDATE ON ap448380.historia
FOR EACH ROW EXECUTE FUNCTION ap448380.aktualizujstatuswypozyczenia();

-- Wstawianie przykładowych danych
INSERT INTO ap448380.galeria (idgaleria, nazwa, adres) VALUES
(1, 'Galeria Sztuki Nowoczesnej', 'Warszawa, ul. Sztuki 1'),
(2, 'Galeria Klasyczna', 'Kraków, ul. Klasyki 10');

INSERT INTO ap448380.artysta (idartysta, imie, nazwisko, urodzenie, smierc) VALUES
(1, 'Vincent', 'van Gogh', '1853-03-30', '1890-07-29'),
(2, 'Pablo', 'Picasso', '1881-10-25', '1973-04-08');

INSERT INTO ap448380.eksponat (ideksponat, idartysta, tytul, typ, wysokosc, szerokosc, waga, wypozyczone) VALUES
(1, 1, 'Gwiaździsta Noc', 1, 73.7, 92.1, 2.5, FALSE),
(2, 2, 'Guernica', 1, 349.3, 776.6, 10.0, FALSE);

