package database

import (
	"context"
	"fmt"
)

// migrateSchoolPart2 creates timetable, attendance, grades, diary,
// meetings, Matrix, and Phase 9 indexes/seed data.
func migrateSchoolPart2(db *DB) error {
	ctx := context.Background()

	migrations := []string{
		// =============================================
		// Stundenplan / Timetable
		// =============================================

		// Timetable slots (Stundenraster)
		`CREATE TABLE IF NOT EXISTS timetable_slots (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			school_id UUID NOT NULL REFERENCES schools(id) ON DELETE CASCADE,
			slot_number INT NOT NULL,
			start_time TIME NOT NULL,
			end_time TIME NOT NULL,
			is_break BOOLEAN DEFAULT FALSE,
			name VARCHAR(50),
			UNIQUE(school_id, slot_number)
		)`,

		// Timetable entries (Stundenplan)
		`CREATE TABLE IF NOT EXISTS timetable_entries (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			school_year_id UUID NOT NULL REFERENCES school_years(id) ON DELETE CASCADE,
			class_id UUID NOT NULL REFERENCES classes(id) ON DELETE CASCADE,
			subject_id UUID NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
			teacher_id UUID NOT NULL REFERENCES teachers(id) ON DELETE CASCADE,
			slot_id UUID NOT NULL REFERENCES timetable_slots(id) ON DELETE CASCADE,
			day_of_week INT NOT NULL CHECK (day_of_week >= 1 AND day_of_week <= 7),
			room VARCHAR(50),
			valid_from DATE NOT NULL,
			valid_until DATE,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Timetable substitutions (Vertretungsplan)
		`CREATE TABLE IF NOT EXISTS timetable_substitutions (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			original_entry_id UUID NOT NULL REFERENCES timetable_entries(id) ON DELETE CASCADE,
			date DATE NOT NULL,
			substitute_teacher_id UUID REFERENCES teachers(id) ON DELETE SET NULL,
			substitute_subject_id UUID REFERENCES subjects(id) ON DELETE SET NULL,
			room VARCHAR(50),
			type VARCHAR(20) NOT NULL,
			note TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			created_by UUID NOT NULL REFERENCES users(id)
		)`,

		// =============================================
		// Abwesenheit / Attendance
		// =============================================

		// Attendance records per lesson
		`CREATE TABLE IF NOT EXISTS attendance_records (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			student_id UUID NOT NULL REFERENCES students(id) ON DELETE CASCADE,
			timetable_entry_id UUID REFERENCES timetable_entries(id) ON DELETE SET NULL,
			date DATE NOT NULL,
			slot_id UUID NOT NULL REFERENCES timetable_slots(id) ON DELETE CASCADE,
			status VARCHAR(30) NOT NULL,
			recorded_by UUID NOT NULL REFERENCES users(id),
			note TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW(),
			UNIQUE(student_id, date, slot_id)
		)`,

		// Absence reports (Krankmeldungen)
		`CREATE TABLE IF NOT EXISTS absence_reports (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			student_id UUID NOT NULL REFERENCES students(id) ON DELETE CASCADE,
			start_date DATE NOT NULL,
			end_date DATE NOT NULL,
			reason TEXT,
			reason_category VARCHAR(30) NOT NULL,
			status VARCHAR(20) NOT NULL DEFAULT 'reported',
			reported_by UUID NOT NULL REFERENCES users(id),
			reported_at TIMESTAMPTZ DEFAULT NOW(),
			confirmed_by UUID REFERENCES users(id),
			confirmed_at TIMESTAMPTZ,
			medical_certificate BOOLEAN DEFAULT FALSE,
			certificate_uploaded BOOLEAN DEFAULT FALSE,
			matrix_notification_sent BOOLEAN DEFAULT FALSE,
			email_notification_sent BOOLEAN DEFAULT FALSE,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Absence notifications to parents
		`CREATE TABLE IF NOT EXISTS absence_notifications (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			attendance_record_id UUID NOT NULL REFERENCES attendance_records(id) ON DELETE CASCADE,
			parent_id UUID NOT NULL REFERENCES parents(id) ON DELETE CASCADE,
			channel VARCHAR(20) NOT NULL,
			message_content TEXT NOT NULL,
			sent_at TIMESTAMPTZ,
			read_at TIMESTAMPTZ,
			response_received BOOLEAN DEFAULT FALSE,
			response_content TEXT,
			response_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// =============================================
		// Notenspiegel / Grades
		// =============================================

		// Grade scales
		`CREATE TABLE IF NOT EXISTS grade_scales (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			school_id UUID NOT NULL REFERENCES schools(id) ON DELETE CASCADE,
			name VARCHAR(50) NOT NULL,
			min_value DECIMAL(5,2) NOT NULL,
			max_value DECIMAL(5,2) NOT NULL,
			passing_value DECIMAL(5,2) NOT NULL,
			is_ascending BOOLEAN DEFAULT FALSE,
			is_default BOOLEAN DEFAULT FALSE,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Grades
		`CREATE TABLE IF NOT EXISTS grades (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			student_id UUID NOT NULL REFERENCES students(id) ON DELETE CASCADE,
			subject_id UUID NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
			teacher_id UUID NOT NULL REFERENCES teachers(id) ON DELETE CASCADE,
			school_year_id UUID NOT NULL REFERENCES school_years(id) ON DELETE CASCADE,
			grade_scale_id UUID NOT NULL REFERENCES grade_scales(id) ON DELETE CASCADE,
			type VARCHAR(30) NOT NULL,
			value DECIMAL(5,2) NOT NULL,
			weight DECIMAL(3,2) DEFAULT 1.0,
			date DATE NOT NULL,
			title VARCHAR(100),
			description TEXT,
			is_visible BOOLEAN DEFAULT TRUE,
			semester INT NOT NULL CHECK (semester IN (1, 2)),
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Grade comments
		`CREATE TABLE IF NOT EXISTS grade_comments (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			grade_id UUID NOT NULL REFERENCES grades(id) ON DELETE CASCADE,
			teacher_id UUID NOT NULL REFERENCES teachers(id) ON DELETE CASCADE,
			comment TEXT NOT NULL,
			is_private BOOLEAN DEFAULT FALSE,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// =============================================
		// Klassenbuch / Class Diary
		// =============================================

		// Class diary entries
		`CREATE TABLE IF NOT EXISTS class_diary_entries (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			class_id UUID NOT NULL REFERENCES classes(id) ON DELETE CASCADE,
			date DATE NOT NULL,
			slot_id UUID NOT NULL REFERENCES timetable_slots(id) ON DELETE CASCADE,
			subject_id UUID NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,
			teacher_id UUID NOT NULL REFERENCES teachers(id) ON DELETE CASCADE,
			topic TEXT,
			homework TEXT,
			homework_due_date DATE,
			materials TEXT,
			notes TEXT,
			is_cancelled BOOLEAN DEFAULT FALSE,
			cancellation_reason TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW(),
			UNIQUE(class_id, date, slot_id)
		)`,

		// =============================================
		// Elterngespräche / Parent Meetings
		// =============================================

		// Parent meeting slots
		`CREATE TABLE IF NOT EXISTS parent_meeting_slots (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			teacher_id UUID NOT NULL REFERENCES teachers(id) ON DELETE CASCADE,
			date DATE NOT NULL,
			start_time TIME NOT NULL,
			end_time TIME NOT NULL,
			location VARCHAR(100),
			is_online BOOLEAN DEFAULT FALSE,
			meeting_link TEXT,
			is_booked BOOLEAN DEFAULT FALSE,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Parent meetings
		`CREATE TABLE IF NOT EXISTS parent_meetings (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			slot_id UUID NOT NULL REFERENCES parent_meeting_slots(id) ON DELETE CASCADE,
			parent_id UUID NOT NULL REFERENCES parents(id) ON DELETE CASCADE,
			student_id UUID NOT NULL REFERENCES students(id) ON DELETE CASCADE,
			topic TEXT,
			notes TEXT,
			status VARCHAR(20) NOT NULL DEFAULT 'scheduled',
			cancelled_at TIMESTAMPTZ,
			cancelled_by UUID REFERENCES users(id),
			cancel_reason TEXT,
			completed_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// =============================================
		// Matrix / Communication Integration
		// =============================================

		// Matrix rooms
		`CREATE TABLE IF NOT EXISTS matrix_rooms (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			school_id UUID NOT NULL REFERENCES schools(id) ON DELETE CASCADE,
			matrix_room_id VARCHAR(255) NOT NULL UNIQUE,
			type VARCHAR(30) NOT NULL,
			class_id UUID REFERENCES classes(id) ON DELETE SET NULL,
			student_id UUID REFERENCES students(id) ON DELETE SET NULL,
			name VARCHAR(255) NOT NULL,
			is_encrypted BOOLEAN DEFAULT TRUE,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Matrix room members
		`CREATE TABLE IF NOT EXISTS matrix_room_members (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			matrix_room_id UUID NOT NULL REFERENCES matrix_rooms(id) ON DELETE CASCADE,
			matrix_user_id VARCHAR(255) NOT NULL,
			user_id UUID REFERENCES users(id) ON DELETE SET NULL,
			power_level INT DEFAULT 0,
			can_write BOOLEAN DEFAULT TRUE,
			joined_at TIMESTAMPTZ DEFAULT NOW(),
			left_at TIMESTAMPTZ,
			UNIQUE(matrix_room_id, matrix_user_id)
		)`,

		// Parent onboarding tokens (QR codes)
		`CREATE TABLE IF NOT EXISTS parent_onboarding_tokens (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			school_id UUID NOT NULL REFERENCES schools(id) ON DELETE CASCADE,
			class_id UUID NOT NULL REFERENCES classes(id) ON DELETE CASCADE,
			student_id UUID NOT NULL REFERENCES students(id) ON DELETE CASCADE,
			token VARCHAR(255) NOT NULL UNIQUE,
			role VARCHAR(30) NOT NULL DEFAULT 'parent',
			expires_at TIMESTAMPTZ NOT NULL,
			used_at TIMESTAMPTZ,
			used_by_user_id UUID REFERENCES users(id),
			created_at TIMESTAMPTZ DEFAULT NOW(),
			created_by UUID NOT NULL REFERENCES users(id)
		)`,

		// =============================================
		// Phase 9 Indexes
		// =============================================
		`CREATE INDEX IF NOT EXISTS idx_schools_active ON schools(is_active)`,
		`CREATE INDEX IF NOT EXISTS idx_school_years_school ON school_years(school_id)`,
		`CREATE INDEX IF NOT EXISTS idx_school_years_current ON school_years(is_current)`,
		`CREATE INDEX IF NOT EXISTS idx_classes_school ON classes(school_id)`,
		`CREATE INDEX IF NOT EXISTS idx_classes_school_year ON classes(school_year_id)`,
		`CREATE INDEX IF NOT EXISTS idx_students_school ON students(school_id)`,
		`CREATE INDEX IF NOT EXISTS idx_students_class ON students(class_id)`,
		`CREATE INDEX IF NOT EXISTS idx_students_user ON students(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_teachers_school ON teachers(school_id)`,
		`CREATE INDEX IF NOT EXISTS idx_teachers_user ON teachers(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_class_teachers_class ON class_teachers(class_id)`,
		`CREATE INDEX IF NOT EXISTS idx_class_teachers_teacher ON class_teachers(teacher_id)`,
		`CREATE INDEX IF NOT EXISTS idx_parents_user ON parents(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_student_parents_student ON student_parents(student_id)`,
		`CREATE INDEX IF NOT EXISTS idx_student_parents_parent ON student_parents(parent_id)`,
		`CREATE INDEX IF NOT EXISTS idx_timetable_entries_class ON timetable_entries(class_id)`,
		`CREATE INDEX IF NOT EXISTS idx_timetable_entries_teacher ON timetable_entries(teacher_id)`,
		`CREATE INDEX IF NOT EXISTS idx_timetable_entries_day ON timetable_entries(day_of_week)`,
		`CREATE INDEX IF NOT EXISTS idx_timetable_substitutions_date ON timetable_substitutions(date)`,
		`CREATE INDEX IF NOT EXISTS idx_timetable_substitutions_entry ON timetable_substitutions(original_entry_id)`,
		`CREATE INDEX IF NOT EXISTS idx_attendance_records_student ON attendance_records(student_id)`,
		`CREATE INDEX IF NOT EXISTS idx_attendance_records_date ON attendance_records(date)`,
		`CREATE INDEX IF NOT EXISTS idx_absence_reports_student ON absence_reports(student_id)`,
		`CREATE INDEX IF NOT EXISTS idx_absence_reports_dates ON absence_reports(start_date, end_date)`,
		`CREATE INDEX IF NOT EXISTS idx_grades_student ON grades(student_id)`,
		`CREATE INDEX IF NOT EXISTS idx_grades_subject ON grades(subject_id)`,
		`CREATE INDEX IF NOT EXISTS idx_grades_teacher ON grades(teacher_id)`,
		`CREATE INDEX IF NOT EXISTS idx_grades_school_year ON grades(school_year_id)`,
		`CREATE INDEX IF NOT EXISTS idx_class_diary_class_date ON class_diary_entries(class_id, date)`,
		`CREATE INDEX IF NOT EXISTS idx_parent_meeting_slots_teacher ON parent_meeting_slots(teacher_id)`,
		`CREATE INDEX IF NOT EXISTS idx_parent_meeting_slots_date ON parent_meeting_slots(date)`,
		`CREATE INDEX IF NOT EXISTS idx_parent_meetings_slot ON parent_meetings(slot_id)`,
		`CREATE INDEX IF NOT EXISTS idx_parent_meetings_parent ON parent_meetings(parent_id)`,
		`CREATE INDEX IF NOT EXISTS idx_matrix_rooms_school ON matrix_rooms(school_id)`,
		`CREATE INDEX IF NOT EXISTS idx_matrix_rooms_class ON matrix_rooms(class_id)`,
		`CREATE INDEX IF NOT EXISTS idx_matrix_room_members_room ON matrix_room_members(matrix_room_id)`,
		`CREATE INDEX IF NOT EXISTS idx_parent_onboarding_tokens_token ON parent_onboarding_tokens(token)`,
		`CREATE INDEX IF NOT EXISTS idx_parent_onboarding_tokens_student ON parent_onboarding_tokens(student_id)`,

		// Insert default grade scales
		`INSERT INTO grade_scales (id, school_id, name, min_value, max_value, passing_value, is_ascending, is_default)
		SELECT gen_random_uuid(), s.id, '1-6 (Noten)', 1, 6, 4, false, true
		FROM schools s
		WHERE NOT EXISTS (SELECT 1 FROM grade_scales gs WHERE gs.school_id = s.id AND gs.name = '1-6 (Noten)')
		ON CONFLICT DO NOTHING`,

		// Insert default timetable slots for schools
		`DO $$
		DECLARE
			school_rec RECORD;
		BEGIN
			FOR school_rec IN SELECT id FROM schools LOOP
				INSERT INTO timetable_slots (school_id, slot_number, start_time, end_time, is_break, name)
				VALUES
					(school_rec.id, 1, '08:00', '08:45', false, '1. Stunde'),
					(school_rec.id, 2, '08:45', '09:30', false, '2. Stunde'),
					(school_rec.id, 3, '09:30', '09:50', true, 'Erste Pause'),
					(school_rec.id, 4, '09:50', '10:35', false, '3. Stunde'),
					(school_rec.id, 5, '10:35', '11:20', false, '4. Stunde'),
					(school_rec.id, 6, '11:20', '11:40', true, 'Zweite Pause'),
					(school_rec.id, 7, '11:40', '12:25', false, '5. Stunde'),
					(school_rec.id, 8, '12:25', '13:10', false, '6. Stunde'),
					(school_rec.id, 9, '13:10', '14:00', true, 'Mittagspause'),
					(school_rec.id, 10, '14:00', '14:45', false, '7. Stunde'),
					(school_rec.id, 11, '14:45', '15:30', false, '8. Stunde')
				ON CONFLICT (school_id, slot_number) DO NOTHING;
			END LOOP;
		END $$`,
	}

	for _, migration := range migrations {
		if _, err := db.Pool.Exec(ctx, migration); err != nil {
			return fmt.Errorf("migrateSchool: %w", err)
		}
	}

	return nil
}
