CREATE SCHEMA IF NOT EXISTS project;
SET search_path = project, public;

-- ========== TABLES ==========

-- USER
CREATE TABLE IF NOT EXISTS "user" (
    id_user       SERIAL PRIMARY KEY,
    username      VARCHAR(50)  NOT NULL UNIQUE,
    name          VARCHAR(100) NOT NULL,
    surname       VARCHAR(100) NOT NULL,
    email         VARCHAR(255) NOT NULL UNIQUE,
    password      VARCHAR(255) NOT NULL
);

-- THERAPIST (extends USER)
CREATE TABLE IF NOT EXISTS therapist (
    id_user              INTEGER PRIMARY KEY,
    office_location      VARCHAR(255) NOT NULL,
    degree               VARCHAR(100) NOT NULL,
    years_exp            INTEGER      NOT NULL CHECK (years_exp >= 0),
    phone_number         VARCHAR(20)  NOT NULL,
    consultation_slots   DATE[],
    CONSTRAINT fk_therapist_user
        FOREIGN KEY (id_user) REFERENCES "user"(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE
);

-- PATIENT (extends USER)
CREATE TABLE IF NOT EXISTS patient (
    id_user      INTEGER PRIMARY KEY,
    id_therapist INTEGER,
    CONSTRAINT fk_patient_user
        FOREIGN KEY (id_user) REFERENCES "user"(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_patient_therapist
        FOREIGN KEY (id_therapist) REFERENCES therapist(id_user)
            ON UPDATE CASCADE ON DELETE SET NULL
);

-- BLOG
CREATE TABLE IF NOT EXISTS blog (
    id_blog      SERIAL PRIMARY KEY,
    id_patient   INTEGER        NOT NULL,
    content      TEXT           NOT NULL,
    title        VARCHAR(200)   NOT NULL,
    date_of_post TIMESTAMPTZ    NOT NULL DEFAULT NOW(),
    CONSTRAINT fk_blog_patient
        FOREIGN KEY (id_patient) REFERENCES patient(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE
);

-- COMMENT
CREATE TABLE IF NOT EXISTS comment (
    id_comment       SERIAL PRIMARY KEY,
    id_blog          INTEGER        NOT NULL,
    id_patient       INTEGER        NOT NULL,
    content          TEXT           NOT NULL,
    date_of_comment  TIMESTAMPTZ    NOT NULL DEFAULT NOW(),
    CONSTRAINT fk_comment_blog
        FOREIGN KEY (id_blog) REFERENCES blog(id_blog)
            ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_comment_patient
        FOREIGN KEY (id_patient) REFERENCES patient(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE
);

-- DIARY
CREATE TABLE IF NOT EXISTS diary (
    id_diary     SERIAL PRIMARY KEY,
    id_patient   INTEGER   NOT NULL,
    date         DATE      NOT NULL,
    daily_rating SMALLINT  NOT NULL CHECK (daily_rating BETWEEN 1 AND 10),
    content      TEXT      NOT NULL,
    CONSTRAINT uq_diary_patient_date UNIQUE (id_patient, date),
    CONSTRAINT fk_diary_patient
        FOREIGN KEY (id_patient) REFERENCES patient(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE
);

-- CONSULTATION
CREATE TABLE IF NOT EXISTS consultation (
    id_consultation  SERIAL PRIMARY KEY,
    id_patient       INTEGER        NOT NULL,
    id_therapist     INTEGER        NOT NULL,
    date             DATE           NOT NULL,
    date_of_payment  DATE           NULL,
    price            DECIMAL(10,2)  NOT NULL CHECK (price >= 0),
    advice           TEXT,
    CONSTRAINT fk_consultation_patient
        FOREIGN KEY (id_patient) REFERENCES patient(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_consultation_therapist
        FOREIGN KEY (id_therapist) REFERENCES therapist(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE
);

-- THERAPY
CREATE TABLE IF NOT EXISTS therapy (
    id_therapy SERIAL PRIMARY KEY,
    name            VARCHAR(100)    NOT NULL,
    dose            VARCHAR(50)     NOT NULL,
    exp_date        DATE            NOT NULL,
    id_consultation INTEGER         NOT NULL,
    CONSTRAINT fk_therapy_consultation
       FOREIGN KEY (id_consultation) REFERENCES consultation(id_consultation)
           ON UPDATE CASCADE ON DELETE CASCADE
);

-- ========== RELATIONS ==========

-- Likes: patients <-> blogs
CREATE TABLE IF NOT EXISTS patient_likes_blog (
    id_patient INTEGER NOT NULL,
    id_blog    INTEGER NOT NULL,
    PRIMARY KEY (id_patient, id_blog),
    CONSTRAINT fk_plb_patient
        FOREIGN KEY (id_patient) REFERENCES patient(id_user)
            ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT fk_plb_blog
        FOREIGN KEY (id_blog) REFERENCES blog(id_blog)
            ON UPDATE CASCADE ON DELETE CASCADE
);

-- ========== INDEXES ==========
CREATE INDEX IF NOT EXISTS idx_patient_therapist
    ON patient (id_therapist);

CREATE INDEX IF NOT EXISTS idx_blog_patient_date
    ON blog (id_patient, date_of_post DESC);

CREATE INDEX IF NOT EXISTS idx_comment_blog_date
    ON comment (id_blog, date_of_comment DESC);

CREATE INDEX IF NOT EXISTS idx_consultation_patient_date
    ON consultation (id_patient, date DESC);

CREATE INDEX IF NOT EXISTS idx_consultation_therapist_date
    ON consultation (id_therapist, date DESC);

