package models

import (
	"time"

	"github.com/google/uuid"
)

// SchoolRole defines roles within the school system
const (
	SchoolRoleTeacher      = "teacher"
	SchoolRoleClassTeacher = "class_teacher"
	SchoolRoleParent       = "parent"
	SchoolRoleParentRep    = "parent_representative"
	SchoolRoleStudent      = "student"
	SchoolRoleAdmin        = "school_admin"
	SchoolRolePrincipal    = "principal"
	SchoolRoleSecretary    = "secretary"
)

// AttendanceStatus defines the status of student attendance
const (
	AttendancePresent         = "present"
	AttendanceAbsent          = "absent"
	AttendanceAbsentExcused   = "excused"
	AttendanceAbsentUnexcused = "unexcused"
	AttendanceLate            = "late"
	AttendanceLateExcused     = "late_excused"
	AttendancePending         = "pending_confirmation"
)

// GradeType defines the type of grade
const (
	GradeTypeExam          = "exam"          // Klassenarbeit/Klausur
	GradeTypeTest          = "test"          // Test/Kurzarbeit
	GradeTypeOral          = "oral"          // Mündlich
	GradeTypeHomework      = "homework"      // Hausaufgabe
	GradeTypeProject       = "project"       // Projekt
	GradeTypeParticipation = "participation" // Mitarbeit
	GradeTypeSemester      = "semester"      // Halbjahres-/Semesternote
	GradeTypeFinal         = "final"         // Endnote/Zeugnisnote
)

// School represents a school/educational institution
type School struct {
	ID               uuid.UUID `json:"id" db:"id"`
	Name             string    `json:"name" db:"name"`
	ShortName        *string   `json:"short_name,omitempty" db:"short_name"`
	Type             string    `json:"type" db:"type"` // 'grundschule', 'hauptschule', 'realschule', 'gymnasium', 'gesamtschule', 'berufsschule'
	Address          *string   `json:"address,omitempty" db:"address"`
	City             *string   `json:"city,omitempty" db:"city"`
	PostalCode       *string   `json:"postal_code,omitempty" db:"postal_code"`
	State            *string   `json:"state,omitempty" db:"state"` // Bundesland
	Country          string    `json:"country" db:"country"`       // Default: DE
	Phone            *string   `json:"phone,omitempty" db:"phone"`
	Email            *string   `json:"email,omitempty" db:"email"`
	Website          *string   `json:"website,omitempty" db:"website"`
	MatrixServerName *string   `json:"matrix_server_name,omitempty" db:"matrix_server_name"`
	LogoURL          *string   `json:"logo_url,omitempty" db:"logo_url"`
	IsActive         bool      `json:"is_active" db:"is_active"`
	CreatedAt        time.Time `json:"created_at" db:"created_at"`
	UpdatedAt        time.Time `json:"updated_at" db:"updated_at"`
}

// SchoolYear represents an academic year
type SchoolYear struct {
	ID        uuid.UUID `json:"id" db:"id"`
	SchoolID  uuid.UUID `json:"school_id" db:"school_id"`
	Name      string    `json:"name" db:"name"` // e.g., "2024/2025"
	StartDate time.Time `json:"start_date" db:"start_date"`
	EndDate   time.Time `json:"end_date" db:"end_date"`
	IsCurrent bool      `json:"is_current" db:"is_current"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// Class represents a school class
type Class struct {
	ID             uuid.UUID `json:"id" db:"id"`
	SchoolID       uuid.UUID `json:"school_id" db:"school_id"`
	SchoolYearID   uuid.UUID `json:"school_year_id" db:"school_year_id"`
	Name           string    `json:"name" db:"name"`   // e.g., "5a", "10b"
	Grade          int       `json:"grade" db:"grade"` // Klassenstufe: 1-13
	Section        *string   `json:"section,omitempty" db:"section"`
	Room           *string   `json:"room,omitempty" db:"room"`
	MatrixInfoRoom *string   `json:"matrix_info_room,omitempty" db:"matrix_info_room"`
	MatrixRepRoom  *string   `json:"matrix_rep_room,omitempty" db:"matrix_rep_room"`
	IsActive       bool      `json:"is_active" db:"is_active"`
	CreatedAt      time.Time `json:"created_at" db:"created_at"`
	UpdatedAt      time.Time `json:"updated_at" db:"updated_at"`
}

// Subject represents a school subject
type Subject struct {
	ID        uuid.UUID `json:"id" db:"id"`
	SchoolID  uuid.UUID `json:"school_id" db:"school_id"`
	Name      string    `json:"name" db:"name"`             // e.g., "Mathematik", "Deutsch"
	ShortName string    `json:"short_name" db:"short_name"` // e.g., "Ma", "De"
	Color     *string   `json:"color,omitempty" db:"color"`
	IsActive  bool      `json:"is_active" db:"is_active"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// Student represents a student
type Student struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	SchoolID      uuid.UUID  `json:"school_id" db:"school_id"`
	ClassID       uuid.UUID  `json:"class_id" db:"class_id"`
	UserID        *uuid.UUID `json:"user_id,omitempty" db:"user_id"`
	StudentNumber *string    `json:"student_number,omitempty" db:"student_number"`
	FirstName     string     `json:"first_name" db:"first_name"`
	LastName      string     `json:"last_name" db:"last_name"`
	DateOfBirth   *time.Time `json:"date_of_birth,omitempty" db:"date_of_birth"`
	Gender        *string    `json:"gender,omitempty" db:"gender"`
	MatrixUserID  *string    `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
	MatrixDMRoom  *string    `json:"matrix_dm_room,omitempty" db:"matrix_dm_room"`
	IsActive      bool       `json:"is_active" db:"is_active"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt     time.Time  `json:"updated_at" db:"updated_at"`
}

// Teacher represents a teacher
type Teacher struct {
	ID           uuid.UUID `json:"id" db:"id"`
	SchoolID     uuid.UUID `json:"school_id" db:"school_id"`
	UserID       uuid.UUID `json:"user_id" db:"user_id"`
	TeacherCode  *string   `json:"teacher_code,omitempty" db:"teacher_code"`
	Title        *string   `json:"title,omitempty" db:"title"`
	FirstName    string    `json:"first_name" db:"first_name"`
	LastName     string    `json:"last_name" db:"last_name"`
	MatrixUserID *string   `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
	IsActive     bool      `json:"is_active" db:"is_active"`
	CreatedAt    time.Time `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time `json:"updated_at" db:"updated_at"`
}

// ClassTeacher assigns teachers to classes (Klassenlehrer)
type ClassTeacher struct {
	ID        uuid.UUID `json:"id" db:"id"`
	ClassID   uuid.UUID `json:"class_id" db:"class_id"`
	TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
	IsPrimary bool      `json:"is_primary" db:"is_primary"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// TeacherSubject assigns subjects to teachers
type TeacherSubject struct {
	ID        uuid.UUID `json:"id" db:"id"`
	TeacherID uuid.UUID `json:"teacher_id" db:"teacher_id"`
	SubjectID uuid.UUID `json:"subject_id" db:"subject_id"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

// Parent represents a parent/guardian
type Parent struct {
	ID               uuid.UUID `json:"id" db:"id"`
	UserID           uuid.UUID `json:"user_id" db:"user_id"`
	MatrixUserID     *string   `json:"matrix_user_id,omitempty" db:"matrix_user_id"`
	FirstName        string    `json:"first_name" db:"first_name"`
	LastName         string    `json:"last_name" db:"last_name"`
	Phone            *string   `json:"phone,omitempty" db:"phone"`
	EmergencyContact bool      `json:"emergency_contact" db:"emergency_contact"`
	CreatedAt        time.Time `json:"created_at" db:"created_at"`
	UpdatedAt        time.Time `json:"updated_at" db:"updated_at"`
}

// StudentParent links students to their parents
type StudentParent struct {
	ID           uuid.UUID `json:"id" db:"id"`
	StudentID    uuid.UUID `json:"student_id" db:"student_id"`
	ParentID     uuid.UUID `json:"parent_id" db:"parent_id"`
	Relationship string    `json:"relationship" db:"relationship"`
	IsPrimary    bool      `json:"is_primary" db:"is_primary"`
	HasCustody   bool      `json:"has_custody" db:"has_custody"`
	CreatedAt    time.Time `json:"created_at" db:"created_at"`
}

// ParentRepresentative assigns parent representatives to classes
type ParentRepresentative struct {
	ID        uuid.UUID  `json:"id" db:"id"`
	ClassID   uuid.UUID  `json:"class_id" db:"class_id"`
	ParentID  uuid.UUID  `json:"parent_id" db:"parent_id"`
	Role      string     `json:"role" db:"role"` // 'first_rep', 'second_rep', 'substitute'
	ElectedAt time.Time  `json:"elected_at" db:"elected_at"`
	ExpiresAt *time.Time `json:"expires_at,omitempty" db:"expires_at"`
	IsActive  bool       `json:"is_active" db:"is_active"`
	CreatedAt time.Time  `json:"created_at" db:"created_at"`
}
