-- ==========================================
-- Инициализация расширений
-- ==========================================
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- ===============================
-- Справочники высшего уровня
-- ===============================
CREATE TABLE IF NOT EXISTS departments (
    id BIGSERIAL UNIQUE PRIMARY KEY NOT NULL,
    name VARCHAR(255) NOT NULL,
    code BIGINT UNIQUE NOT NULL
);

INSERT INTO departments (name, code) VALUES
    ('Кафедра ИБ', 1),
    ('Кафедра ВТ', 2),
    ('Кафедра КТ', 3);

CREATE TABLE IF NOT EXISTS specialties (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    specialty_code VARCHAR(255) NOT NULL
);

INSERT INTO specialties (name, specialty_code) VALUES
    ('Информационная безопасность', '10.03.01'),
    ('Информатика и вычислительная техника', '09.03.01'),
    ('Программная инженерия', '09.03.04');

-- ==========================================
-- Пользователи и роли
-- ==========================================
CREATE TABLE IF NOT EXISTS users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    role VARCHAR(20) NOT NULL DEFAULT 'STUDENT',
    full_name VARCHAR(255) NOT NULL,
    job_title VARCHAR(255) NOT NULL,
    department_id BIGINT NOT NULL REFERENCES departments(id),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Админ по умолчанию: admin / admin (bcrypt через pgcrypto)
INSERT INTO users (username, password, role, full_name, job_title, department_id)
VALUES ('admin', crypt('admin', gen_salt('bf', 10)), 'ADMIN', 'Иванов Админ Иванович', 'Доцент', 1),
       ('Тестовый преподаватель', crypt('1234567890', gen_salt('bf', 10)), 'TEACHER', 'Петров Препод Петрович', 'Профессор', 2)
ON CONFLICT (username) DO NOTHING;

-- ==========================================
-- Образовательные формы
-- ==========================================
CREATE TABLE IF NOT EXISTS education_forms (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(100) UNIQUE NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO education_forms (name) VALUES 
    ('Бакалавриат'), 
    ('Магистратура'), 
    ('Специалитет')
ON CONFLICT (name) DO NOTHING;

-- ==========================================
-- Учебные группы
-- ==========================================
CREATE TABLE IF NOT EXISTS student_groups (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(100) UNIQUE NOT NULL,
    group_size BIGINT NOT NULL,
    education_form_id BIGINT NOT NULL REFERENCES education_forms(id),
    department_id BIGINT NOT NULL REFERENCES departments(id),
    course INT CHECK (course BETWEEN 1 AND 6),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Тестовая базовая группа для работы
INSERT INTO student_groups (name, group_size, education_form_id, department_id, course)
VALUES ('ИВТ-21-1', 25, 1, 1, 3),
       ('ИБ-41м', 15, 2, 1, 2)
ON CONFLICT (name) DO NOTHING;

-- ==========================================
-- Подгруппы (например: "ИВТ-21-1 Подгруппа 1")
-- ==========================================
CREATE TABLE IF NOT EXISTS subgroups (
    id BIGSERIAL PRIMARY KEY,
    group_id BIGINT NOT NULL REFERENCES student_groups(id) ON DELETE CASCADE,
    name VARCHAR(100) NOT NULL,
    student_capacity INT,
    UNIQUE(group_id, name)
);

-- ==========================================
-- Справочники
-- ==========================================

-- Дисциплины
CREATE TABLE IF NOT EXISTS subjects (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(200) UNIQUE NOT NULL,
    code VARCHAR(20),
    department_id BIGINT NOT NULL REFERENCES departments(id),
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO subjects (name, department_id) VALUES 
    ('Высшая математика', 1), 
    ('Философия', 1), 
    ('Информатика', 1), 
    ('Базы данных', 1),
    ('Английский язык', 1)
ON CONFLICT (name) DO NOTHING;

-- Типы занятий
CREATE TABLE IF NOT EXISTS lesson_types (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(50) UNIQUE NOT NULL,
    color_code VARCHAR(7) DEFAULT '#3788d8',
    duration_minutes INT DEFAULT 90
);

INSERT INTO lesson_types (name, color_code) VALUES 
    ('Лекция', '#FF6B6B'),
    ('Практика', '#4ECDC4'),
    ('Лабораторная работа', '#45B7D1')
ON CONFLICT (name) DO NOTHING;

-- Оборудование
CREATE TABLE IF NOT EXISTS equipments (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(50) UNIQUE NOT NULL,
    description TEXT,
    inventory_number VARCHAR(50)
);

INSERT INTO equipments (name) VALUES 
    ('Проектор'), 
    ('ПК'), 
    ('Лаборатория'),
    ('Интерактивная доска'),
    ('Документ-камера'),
    ('Аудиосистема')
ON CONFLICT (name) DO NOTHING;

-- Аудитории
CREATE TABLE IF NOT EXISTS classrooms (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(50) UNIQUE NOT NULL,
    capacity INT NOT NULL CHECK (capacity > 0),
    building VARCHAR(50),
    floor INT,
    is_available BOOLEAN DEFAULT TRUE,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO classrooms (name, capacity, building, floor) VALUES 
    ('101 Ленинская', 120, 'Главный корпус', 1),
    ('202 IT Lab', 20, 'Корпус IT', 2),
    ('303 Обычная', 30, 'Главный корпус', 3)
ON CONFLICT (name) DO NOTHING;

-- Привязка оборудования к аудиториям (Many-to-Many)
CREATE TABLE IF NOT EXISTS classroom_equipments (
    classroom_id BIGINT NOT NULL REFERENCES classrooms(id) ON DELETE CASCADE,
    equipment_id BIGINT NOT NULL REFERENCES equipments(id) ON DELETE CASCADE,
    quantity INT DEFAULT 1 CHECK (quantity > 0),
    notes TEXT,
    PRIMARY KEY (classroom_id, equipment_id)
);

INSERT INTO classroom_equipments (classroom_id, equipment_id, quantity)
SELECT c.id, e.id, 
    CASE 
        WHEN e.name = 'ПК' AND c.name = '202 IT Lab' THEN 15
        WHEN e.name = 'ПК' THEN 1
        ELSE 1
    END
FROM classrooms c, equipments e 
WHERE 
    (c.name = '101 Ленинская' AND e.name IN ('Проектор', 'Интерактивная доска', 'Аудиосистема'))
    OR (c.name = '202 IT Lab' AND e.name IN ('ПК', 'Проектор', 'Лаборатория', 'Интерактивная доска'))
    OR (c.name = '303 Обычная' AND e.name IN ('Проектор'))
ON CONFLICT (classroom_id, equipment_id) DO NOTHING;

-- ==========================================
-- Связи для преподавателей
-- ==========================================

CREATE TABLE IF NOT EXISTS teacher_subjects (
    user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    subject_id BIGINT NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
    qualification_level VARCHAR(50),
    experience_years INT,
    PRIMARY KEY(user_id, subject_id)
);

CREATE TABLE IF NOT EXISTS teacher_lesson_types (
    user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    subject_id BIGINT NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
    lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id) ON DELETE CASCADE,
    PRIMARY KEY (user_id, subject_id, lesson_type_id)
);

-- ==========================================
-- Основная таблица Расписания (Lessons)
-- ==========================================
CREATE TABLE IF NOT EXISTS lessons (
    id BIGSERIAL PRIMARY KEY,
    teacher_id BIGINT NOT NULL REFERENCES users(id),
    group_id BIGINT NOT NULL REFERENCES student_groups(id),
    subject_id  BIGINT NOT NULL REFERENCES subjects(id),
    lesson_format VARCHAR(255) NOT NULL,
    type_lesson VARCHAR(255) NOT NULL,
    classroom_id BIGINT NOT NULL REFERENCES classrooms(id),
    day VARCHAR(255) NOT NULL,
    week VARCHAR(255) NOT NULL,
    time VARCHAR(255) NOT NULL
);

INSERT INTO lessons (teacher_id, group_id, subject_id, lesson_format, type_lesson, classroom_id, day, week, time) VALUES
    (2, 1, 1, 'Очно', 'Лекция', 1, 'Понедельник', 'Верхняя', '11:40 - 13:10'),
    (1, 1, 2, 'Онлайн', 'Практическая работа', 2, 'Вторник', 'Нижняя', '15:00 - 16:30'),
    (2, 1, 3, 'Очно', 'Лабораторная работа', 3, 'Среда', 'Верхняя', '8:00 - 9:30'),
    (1, 1, 4, 'Онлайн', 'Лекция', 1, 'Четверг', 'Нижняя', '11:40 - 13:10'),
    (2, 1, 5, 'Очно', 'Практическая работа', 2, 'Пятница', 'Верхняя', '15:00 - 16:30'),
    (1, 1, 3, 'Онлайн', 'Лабораторная работа', 3, 'Суббота', 'Нижняя', '8:00 - 9:30');

-- ===============================
-- Создание таблицы данных расписания (schedule_data)
-- ===============================
CREATE TABLE IF NOT EXISTS schedule_data (
    id BIGSERIAL PRIMARY KEY,
    department_id BIGINT NOT NULL REFERENCES departments(id),
    semester INT NOT NULL,
    group_id BIGINT NOT NULL REFERENCES student_groups(id),
    subjects_id BIGINT NOT NULL REFERENCES subjects(id),
    lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id),
    number_of_hours INT NOT NULL,
    is_division BOOLEAN NOT NULL DEFAULT FALSE,
    teacher_id BIGINT NOT NULL REFERENCES users(id),
    semester_type VARCHAR(255) NOT NULL,
    period VARCHAR(255) NOT NULL
);

INSERT INTO schedule_data (department_id, semester, group_id, subjects_id, lesson_type_id, number_of_hours, is_division, teacher_id, semester_type, period)
VALUES (1, 1, 1, 1, 3, 2, true, 1, 'Весенний', '2024/2025'),
       (2, 4, 2, 3, 2, 1, false, 2, 'Осенний', '2025/2026'),
       (3, 5, 1, 2, 1, 3, true, 1, 'Весенний', '2023/2024');

-- ==========================================
-- Функция обновления timestamp
-- ==========================================
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER update_users_updated_at
    BEFORE UPDATE ON users
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- ==========================================
-- Комментарии к таблицам и полям (для документации)
-- ==========================================
COMMENT ON TABLE users IS 'Пользователи системы (студенты, преподаватели, администраторы)';
COMMENT ON TABLE lessons IS 'Основное расписание занятий';
COMMENT ON TABLE departments IS 'Кафедры';
COMMENT ON TABLE specialties IS 'Специальности';
COMMENT ON TABLE schedule_data IS 'Данные к составлению расписания';
COMMENT ON COLUMN schedule_data.department_id IS 'Идентификатор кафедры';
COMMENT ON COLUMN schedule_data.semester IS 'Номер семестра';
COMMENT ON COLUMN schedule_data.group_id IS 'Идентификатор группы';
COMMENT ON COLUMN schedule_data.subjects_id IS 'Идентификатор предмета';
COMMENT ON COLUMN schedule_data.lesson_type_id IS 'Идентификатор типа занятия';
COMMENT ON COLUMN schedule_data.number_of_hours IS 'Количество часов';
COMMENT ON COLUMN schedule_data.is_division IS 'Является ли занятие разделенным';
COMMENT ON COLUMN schedule_data.teacher_id IS 'Идентификатор преподавателя';
COMMENT ON COLUMN schedule_data.semester_type IS 'Тип семестра (Весенний, Осенний)';
COMMENT ON COLUMN schedule_data.period IS 'Период занятий (год/год)';

COMMENT ON TABLE education_forms IS 'Формы обучения';
COMMENT ON TABLE subgroups IS 'Подгруппы';
COMMENT ON TABLE lesson_types IS 'Типы занятий';
COMMENT ON TABLE equipments IS 'Оборудование';
COMMENT ON TABLE classrooms IS 'Аудитории';
COMMENT ON TABLE classroom_equipments IS 'Привязка оборудования к аудиториям';
COMMENT ON TABLE teacher_subjects IS 'Привязка преподавателей к дисциплинам';
COMMENT ON TABLE teacher_lesson_types IS 'Типы занятий преподавателя';

COMMENT ON COLUMN users.id IS 'ID пользователя';
COMMENT ON COLUMN users.username IS 'Логин пользователя';
COMMENT ON COLUMN users.password IS 'Хэш пароля пользователя';
COMMENT ON COLUMN users.role IS 'Роль пользователя';
COMMENT ON COLUMN users.created_at IS 'Дата и время создания';
COMMENT ON COLUMN users.updated_at IS 'Дата и время последнего обновления';
COMMENT ON COLUMN users.full_name IS 'ФИО пользователя';
COMMENT ON COLUMN users.job_title IS 'Должность пользователя';
COMMENT ON COLUMN users.department_id IS 'ID кафедры';

COMMENT ON COLUMN education_forms.id IS 'ID формы обучения';
COMMENT ON COLUMN education_forms.name IS 'Название формы обучения';
COMMENT ON COLUMN education_forms.description IS 'Описание';
COMMENT ON COLUMN education_forms.created_at IS 'Дата и время создания';

COMMENT ON COLUMN student_groups.id IS 'ID учебной группы';
COMMENT ON COLUMN student_groups.name IS 'Название группы';
COMMENT ON COLUMN student_groups.group_size IS 'Количество студентов';
COMMENT ON COLUMN student_groups.education_form_id IS 'ID формы обучения, к которой относится группа';
COMMENT ON COLUMN student_groups.department_id IS 'ID кафедры';
COMMENT ON COLUMN student_groups.course IS 'Курс';
COMMENT ON COLUMN student_groups.created_at IS 'Дата и время создания';

COMMENT ON COLUMN subgroups.id IS 'ID подгруппы';
COMMENT ON COLUMN subgroups.group_id IS 'ID учебной группы, к которой относится подгруппа';
COMMENT ON COLUMN subgroups.name IS 'Название подгруппы';
COMMENT ON COLUMN subgroups.student_capacity IS 'Количество студентов в подгруппе';

COMMENT ON COLUMN subjects.id IS 'ID предмета';
COMMENT ON COLUMN subjects.name IS 'Название предмета';
COMMENT ON COLUMN subjects.code IS 'Код предмета';
COMMENT ON COLUMN subjects.department_id IS 'ID кафедры';
COMMENT ON COLUMN subjects.description IS 'Описание предмета';
COMMENT ON COLUMN subjects.created_at IS 'Дата и время создания';

COMMENT ON COLUMN lesson_types.id IS 'ID урока';
COMMENT ON COLUMN lesson_types.name IS 'Название типа урока';
COMMENT ON COLUMN lesson_types.color_code IS 'Цветовой код для типа урока';
COMMENT ON COLUMN lesson_types.duration_minutes IS 'Длительность урока в минутах';

COMMENT ON COLUMN equipments.id IS 'ID оборудования';
COMMENT ON COLUMN equipments.name IS 'Название оборудования';
COMMENT ON COLUMN equipments.description IS 'Описание оборудования';
COMMENT ON COLUMN equipments.inventory_number IS 'Инвентарный номер оборудования';

COMMENT ON COLUMN classrooms.id IS 'ID аудитории';
COMMENT ON COLUMN classrooms.name IS 'Название аудитории';
COMMENT ON COLUMN classrooms.capacity IS 'Вместимость аудитории';
COMMENT ON COLUMN classrooms.building IS 'Корпус';
COMMENT ON COLUMN classrooms.floor IS 'Этаж';
COMMENT ON COLUMN classrooms.is_available IS 'Доступность аудитории';
COMMENT ON COLUMN classrooms.description IS 'Описание аудитории';
COMMENT ON COLUMN classrooms.created_at IS 'Дата и время создания';

COMMENT ON COLUMN classroom_equipments.classroom_id IS 'ID аудитории';
COMMENT ON COLUMN classroom_equipments.equipment_id IS 'ID оборудования';
COMMENT ON COLUMN classroom_equipments.quantity IS 'Дата и время создания'; -- Так было в V2
COMMENT ON COLUMN classroom_equipments.notes IS 'Примечания к записи';

COMMENT ON COLUMN teacher_subjects.user_id IS 'ID преподавателя';
COMMENT ON COLUMN teacher_subjects.subject_id IS 'ID предмета';
COMMENT ON COLUMN teacher_subjects.qualification_level IS 'Уровень квалификации преподавателя';
COMMENT ON COLUMN teacher_subjects.experience_years IS 'Опыт преподавания';

COMMENT ON COLUMN lessons.id IS 'ID урока';
COMMENT ON COLUMN lessons.teacher_id IS 'Идентификатор преподавателя, который проводит урок';
COMMENT ON COLUMN lessons.group_id IS 'ID группы, в которой проходит урок';
COMMENT ON COLUMN lessons.subject_id IS 'ID предмета, который преподается';
COMMENT ON COLUMN lessons.lesson_format IS 'Формат урока';
COMMENT ON COLUMN lessons.type_lesson IS 'Тип урока';
COMMENT ON COLUMN lessons.classroom_id IS 'ID аудитории, в которой проходит урок';
COMMENT ON COLUMN lessons.day IS 'День недели, в который проходит урок';
COMMENT ON COLUMN lessons.week IS 'Номер недели, в которой проходит урок';
COMMENT ON COLUMN lessons.time IS 'Время урока';

COMMENT ON COLUMN departments.id IS 'ID кафедры';
COMMENT ON COLUMN departments.name IS 'Название кафедры';
COMMENT ON COLUMN departments.code IS 'Код кафедры';

COMMENT ON COLUMN specialties.id IS 'ID специальности';
COMMENT ON COLUMN specialties.name IS 'Название специальности';
COMMENT ON COLUMN specialties.specialty_code IS 'Код специальности';

COMMENT ON COLUMN teacher_lesson_types.user_id IS 'ID преподавателя';
COMMENT ON COLUMN teacher_lesson_types.subject_id IS 'ID предмета';
COMMENT ON COLUMN teacher_lesson_types.lesson_type_id IS 'ID типа занятия';