DROP VIEW IF EXISTS aktualne_lok_all;

-- Create tables
CREATE TABLE ARTYSTA (
    artysta_id SERIAL PRIMARY KEY,
    imie VARCHAR(100) NOT NULL,
    nazwisko VARCHAR(100),
    rok_urodzenia INTEGER,
    rok_smierci INTEGER
);

CREATE TABLE EKSPONAT (
    eksponat_id SERIAL PRIMARY KEY,
    tytul VARCHAR(255) NOT NULL,
    rodzaj VARCHAR(100) NOT NULL,
    wysokosc DECIMAL(8,2) NOT NULL,
    szerokosc DECIMAL(8,2) NOT NULL,
    waga DECIMAL(8,2) NOT NULL,
    czy_cenny BOOLEAN NOT NULL DEFAULT FALSE,
    artysta_id INTEGER REFERENCES ARTYSTA(artysta_id)
);

CREATE TABLE GALERIA (
    galeria_id SERIAL PRIMARY KEY,
    nazwa VARCHAR(255) NOT NULL
);

CREATE TABLE INSTYTUCJA (
    instytucja_id SERIAL PRIMARY KEY,
    nazwa VARCHAR(255) NOT NULL,
    miasto VARCHAR(100) NOT NULL
);

CREATE TABLE HISTORIA_LOKALIZACJI (
    historia_id SERIAL PRIMARY KEY,
    eksponat_id INTEGER NOT NULL REFERENCES EKSPONAT(eksponat_id),
    status VARCHAR(50) NOT NULL CHECK (status IN ('GALERIA', 'WYPOZYCZENIE', 'MAGAZYN')),
    data_rozpoczecia DATE NOT NULL,
    data_zakonczenia DATE CHECK (data_zakonczenia IS NULL OR data_zakonczenia >= data_rozpoczecia)
);

CREATE TABLE UMIESZCZENIE_W_GALERII (
    umieszczenie_id SERIAL PRIMARY KEY,
    historia_id INTEGER NOT NULL UNIQUE REFERENCES HISTORIA_LOKALIZACJI(historia_id),
    galeria_id INTEGER NOT NULL REFERENCES GALERIA(galeria_id)
);

CREATE TABLE WYPOZYCZENIE (
    wypozyczenie_id SERIAL PRIMARY KEY,
    historia_id INTEGER NOT NULL UNIQUE REFERENCES HISTORIA_LOKALIZACJI(historia_id),
    instytucja_id INTEGER NOT NULL REFERENCES INSTYTUCJA(instytucja_id)
);

CREATE TABLE MAGAZYN (
    magazyn_id SERIAL PRIMARY KEY,
    historia_id INTEGER NOT NULL UNIQUE REFERENCES HISTORIA_LOKALIZACJI(historia_id),
    powod VARCHAR(255) NOT NULL
);

CREATE OR REPLACE FUNCTION sprawdz_czas_wypozyczenia(eksponat_id INT) RETURNS BOOLEAN AS $$
DECLARE
    laczny_czas INT;
BEGIN
    SELECT SUM(DATE_PART('day', data_zakonczenia - data_rozpoczecia))
    INTO laczny_czas
    FROM HISTORIA_LOKALIZACJI hl
    JOIN WYPOZYCZENIE w ON hl.historia_id = w.historia_id
    WHERE hl.eksponat_id = eksponat_id AND hl.status = 'WYPOZYCZENIE';

    IF laczny_czas > 30 THEN
        RETURN FALSE;
    END IF;

    RETURN TRUE;
END;
$$
 LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION dodaj_eksponat_z_artysta(
    p_tytul VARCHAR(255),
    p_rodzaj VARCHAR(100),
    p_wysokosc DECIMAL(8,2),
    p_szerokosc DECIMAL(8,2),
    p_waga DECIMAL(8,2),
    p_czy_cenny BOOLEAN,
    p_imie_artysty VARCHAR(100) DEFAULT NULL,
    p_nazwisko_artysty VARCHAR(100) DEFAULT NULL,
    p_rok_urodzenia INTEGER DEFAULT NULL,
    p_rok_smierci INTEGER DEFAULT NULL
) RETURNS VOID AS $$
DECLARE
    v_artysta_id INTEGER;
BEGIN
    -- Check if the artist already exists based on provided name and surname
    IF p_imie_artysty IS NOT NULL AND p_nazwisko_artysty IS NOT NULL THEN
        SELECT artysta_id INTO v_artysta_id
        FROM ARTYSTA
        WHERE imie = p_imie_artysty AND nazwisko = p_nazwisko_artysty;
    ELSIF p_imie_artysty IS NOT NULL THEN
        SELECT artysta_id INTO v_artysta_id
        FROM ARTYSTA
        WHERE imie = p_imie_artysty;
    ELSIF p_nazwisko_artysty IS NOT NULL THEN
        SELECT artysta_id INTO v_artysta_id
        FROM ARTYSTA
        WHERE nazwisko = p_nazwisko_artysty;
    END IF;

    -- If the artist does not exist, insert a new artist
    IF v_artysta_id IS NULL THEN
        INSERT INTO ARTYSTA (imie, nazwisko, rok_urodzenia, rok_smierci)
        VALUES (p_imie_artysty, p_nazwisko_artysty, p_rok_urodzenia, p_rok_smierci)
        RETURNING artysta_id INTO v_artysta_id;
    END IF;

    -- Insert the new eksponat with the artist_id
    INSERT INTO EKSPONAT (tytul, rodzaj, wysokosc, szerokosc, waga, czy_cenny, artysta_id)
    VALUES (p_tytul, p_rodzaj, p_wysokosc, p_szerokosc, p_waga, p_czy_cenny, v_artysta_id);
END;
$$ LANGUAGE plpgsql;


CREATE OR REPLACE FUNCTION pokaz_aktualna_lokalizacje(p_eksponat_id INT) 
RETURNS TABLE (
    eksponat_id INT,
    tytul VARCHAR(255),
    status VARCHAR(50),
    galeria_nazwa VARCHAR(255),
    instytucja_nazwa VARCHAR(255),
    magazyn_powod VARCHAR(255)
) AS $$
BEGIN
    RETURN QUERY
    SELECT 
        e.eksponat_id,
        e.tytul,
        hl.status,
        g.nazwa AS galeria_nazwa,
        i.nazwa AS instytucja_nazwa,
        m.powod AS magazyn_powod
    FROM 
        EKSPONAT e
    LEFT JOIN 
        HISTORIA_LOKALIZACJI hl ON e.eksponat_id = hl.eksponat_id
    LEFT JOIN 
        UMIESZCZENIE_W_GALERII ug ON hl.historia_id = ug.historia_id
    LEFT JOIN 
        GALERIA g ON ug.galeria_id = g.galeria_id
    LEFT JOIN 
        WYPOZYCZENIE w ON hl.historia_id = w.historia_id
    LEFT JOIN 
        INSTYTUCJA i ON w.instytucja_id = i.instytucja_id
    LEFT JOIN 
        MAGAZYN m ON hl.historia_id = m.historia_id
    WHERE 
        e.eksponat_id = p_eksponat_id
        AND hl.data_zakonczenia IS NULL;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE VIEW aktualne_lok_all AS
SELECT 
    e.eksponat_id,
    l.tytul,
    l.status,
    l.galeria_nazwa,
    l.instytucja_nazwa,
    l.magazyn_powod
FROM 
    EKSPONAT e
CROSS JOIN LATERAL (
    SELECT * FROM pokaz_aktualna_lokalizacje(e.eksponat_id)
) l;


CREATE OR REPLACE FUNCTION przenies_eksponat(
    p_eksponat_id INT,
    p_nowy_status VARCHAR(50),
    p_galeria_id INT DEFAULT NULL,
    p_powod_magazyn VARCHAR(255) DEFAULT NULL
) RETURNS VOID AS $$
DECLARE
    v_historia_id INT;
BEGIN
    -- Ensure the new status is valid
    IF p_nowy_status NOT IN ('GALERIA', 'MAGAZYN') THEN
        RAISE EXCEPTION 'Nieprawidłowy status. Dozwolone wartości to "GALERIA" lub "MAGAZYN".';
    END IF;

    -- End the current location history for the eksponat
    UPDATE HISTORIA_LOKALIZACJI
    SET data_zakonczenia = CURRENT_DATE
    WHERE eksponat_id = p_eksponat_id
      AND data_zakonczenia IS NULL;

    -- Insert a new row into HISTORIA_LOKALIZACJI for the new status
    INSERT INTO HISTORIA_LOKALIZACJI (eksponat_id, status, data_rozpoczecia)
    VALUES (p_eksponat_id, p_nowy_status, CURRENT_DATE)
    RETURNING historia_id INTO v_historia_id;

    -- If moving to GALERIA, insert into UMIESZCZENIE_W_GALERII
    IF p_nowy_status = 'GALERIA' THEN
        IF p_galeria_id IS NULL THEN
            RAISE EXCEPTION 'ID galerii musi być podane przy przenoszeniu do galerii.';
        END IF;

        INSERT INTO UMIESZCZENIE_W_GALERII (historia_id, galeria_id)
        VALUES (v_historia_id, p_galeria_id);

    -- If moving to MAGAZYN, insert into MAGAZYN
    ELSIF p_nowy_status = 'MAGAZYN' THEN
        IF p_powod_magazyn IS NULL THEN
            RAISE EXCEPTION 'Powód przeniesienia do magazynu musi być podany.';
        END IF;

        INSERT INTO MAGAZYN (historia_id, powod)
        VALUES (v_historia_id, p_powod_magazyn);
    END IF;
END;
$$ LANGUAGE plpgsql;






-- Insert sample data
INSERT INTO ARTYSTA (imie, nazwisko, rok_urodzenia, rok_smierci) VALUES
('Leonardo', 'da Vinci', 1452, 1519),
('Vincent', 'van Gogh', 1853, 1890),
('Pablo', 'Picasso', 1881, 1973),
('Frida', 'Kahlo', 1907, 1954);

INSERT INTO EKSPONAT (tytul, rodzaj, wysokosc, szerokosc, waga, czy_cenny, artysta_id) VALUES
('Mona Lisa', 'Obraz', 77, 53, 8.8, true, 1),
('Słoneczniki', 'Obraz', 92, 73, 10.0, true, 2),
('Guernica', 'Obraz', 349, 776, 90.0, true, 3),
('Autoportret z naszyjnikiem', 'Obraz', 63, 49, 5.5, false, 4);

INSERT INTO GALERIA (nazwa) VALUES
('Galeria Główna'),
('Galeria Sztuki Nowoczesnej'),
('Galeria Portretów');

INSERT INTO INSTYTUCJA (nazwa, miasto) VALUES
('Muzeum Narodowe', 'Warszawa'),
('Galeria Sztuki Współczesnej', 'Kraków'),
('Centrum Sztuki Nowoczesnej', 'Gdańsk');

-- Insert current locations
INSERT INTO HISTORIA_LOKALIZACJI (eksponat_id, status, data_rozpoczecia) VALUES
(1, 'GALERIA', '2024-01-01'),
(2, 'GALERIA', '2024-01-01'),
(3, 'MAGAZYN', '2024-01-01'),
(4, 'GALERIA', '2024-01-01');

INSERT INTO UMIESZCZENIE_W_GALERII (historia_id, galeria_id) VALUES
(1, 1),
(2, 2),
(4, 3);

INSERT INTO MAGAZYN (historia_id, powod) VALUES
(3, 'Konserwacja');