

CREATE TABLE role (
    role_id SERIAL PRIMARY KEY,
    name VARCHAR(50) UNIQUE NOT NULL, -- admin, volunteer, team_lead, manager, terry
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

-- COMBINED: users + admin_settings in one table
CREATE TABLE users (
    user_id SERIAL PRIMARY KEY,
    first_name VARCHAR(100),
    last_name VARCHAR(100),
    email VARCHAR(150) UNIQUE NOT NULL,
    phone VARCHAR(20) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE address_database (
    address_id SERIAL PRIMARY KEY,
    address VARCHAR(255),
    street_name VARCHAR(100),
    street_type VARCHAR(50),
    street_quadrant VARCHAR(50),
    house_number VARCHAR(20),
    house_alpha VARCHAR(10),
    postal_code VARCHAR(10),
    longitude DECIMAL(9,6),
    latitude DECIMAL(9,6),
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE team (
    team_id SERIAL PRIMARY KEY,
    team_lead_id INT REFERENCES users(user_id) ON DELETE SET NULL,
    volunteer_id INT REFERENCES users(user_id) ON DELETE SET NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE admin_volunteers (
    admin_id INT REFERENCES users(user_id) ON DELETE CASCADE,
    volunteer_id INT REFERENCES users(user_id) ON DELETE CASCADE,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY (admin_id, volunteer_id)
);

CREATE TABLE appointment (
    sched_id SERIAL PRIMARY KEY,
    user_id INT REFERENCES users(user_id) ON DELETE CASCADE,
    address_id INT REFERENCES address_database(address_id) ON DELETE CASCADE,
    appointment_date DATE,
    appointment_time TIME,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE poll(
    poll_id          SERIAL PRIMARY KEY,
    user_id          INTEGER REFERENCES users ON DELETE CASCADE,
    address_id       INTEGER REFERENCES address_database ON DELETE CASCADE,
    donation_amount  integer default 0,
    is_active        BOOLEAN DEFAULT TRUE,
    created_at       TIMESTAMP DEFAULT NOW(),
    updated_at       TIMESTAMP DEFAULT NOW()
);

CREATE TABLE poll_response
(
    poll_response_id         SERIAL PRIMARY KEY,
    poll_id                  INTEGER REFERENCES poll(poll_id) ON DELETE CASCADE,
    respondent_postal_code   VARCHAR(10),        -- Postal code of respondent
    question1_voted_before   BOOLEAN,            -- Have you voted before?
    question2_vote_again     BOOLEAN,            -- Will you vote again for this candidate?
    question3_lawn_signs     INTEGER DEFAULT 0,   -- How many lawn signs needed
    question4_banner_signs   INTEGER DEFAULT 0,   -- How many banner signs needed
    question5_thoughts       TEXT,               -- Write your thoughts
    signage_status          VARCHAR(50) DEFAULT 'requested' CHECK (signage_status IN ('requested', 'delivered', 'cancelled')),
    is_active               BOOLEAN DEFAULT TRUE,
    created_at              TIMESTAMP DEFAULT NOW(),
    updated_at              TIMESTAMP DEFAULT NOW()
);

CREATE TABLE post (
    post_id SERIAL PRIMARY KEY,
    author_id INT REFERENCES users(user_id) ON DELETE CASCADE,
    content TEXT,
    image_url TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE availability (
    sched_id SERIAL PRIMARY KEY,
    user_id INT REFERENCES users(user_id) ON DELETE CASCADE,
    day_of_week VARCHAR(20),
    start_time TIME,
    end_time TIME,
    created_at TIMESTAMP DEFAULT NOW()
);

-- Indexes for better performance
CREATE INDEX idx_poll_response_poll_id ON poll_response(poll_id);
CREATE INDEX idx_poll_response_postal_code ON poll_response(respondent_postal_code);
CREATE INDEX idx_poll_response_signage_status ON poll_response(signage_status);
CREATE INDEX idx_poll_user_id ON poll(user_id);

-- Function to generate a 6-character random admin code
CREATE OR REPLACE FUNCTION generate_admin_code()
RETURNS trigger AS $$
BEGIN
    IF (SELECT name FROM role WHERE role_id = NEW.role_id) = 'admin' THEN
        NEW.admin_code := substring(md5(random()::text) FROM 1 FOR 6);
    ELSE
        NEW.admin_code := NULL;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger to automatically generate admin_code on INSERT
CREATE TRIGGER set_admin_code
BEFORE INSERT ON users
FOR EACH ROW
EXECUTE PROCEDURE generate_admin_code();


INSERT INTO role (role_id, name) VALUES
(1, 'admin'),
(2, 'team_lead'),
(3, 'volunteer')
ON CONFLICT DO NOTHING;

ALTER TABLE availability
ADD CONSTRAINT availability_user_day_unique UNIQUE (user_id, day_of_week);
