import { Sequelize } from "sequelize";
import db from "../database/db.js";
import UserModel from "./usersModels/userModel.js";
import TeacherModel from "./usersModels/teacherModel.js";
import StudentModel from "./usersModels/studentModel.js";
import SectionModel from "./contentModels/sectionModel.js";
import TopicModel from "./contentModels/topicModel.js";
import LevelModel from "./contentModels/levelModel.js";
import ExerciseModel from "./contentModels/exerciseModel.js";
import MultipleChoicesModel from "./exerciseTypesModels/multipleChoicesModel.js";
import MatchingPairsModel from "./exerciseTypesModels/matchingPairsModel.js";
import TrueFalseModel from "./exerciseTypesModels/trueFalseModel.js";
import StdLearningModel from "./learningModels/stdLearningModel.js";
import StdExerciseModel from "./learningModels/stdExerciseModel.js";
import ClassModel from "./monitoringModels/classModel.js";
import MonitoringModel from "./monitoringModels/monitoringModel.js";
import ReportModel from "./usersModels/reportModel.js";

const Op = Sequelize.Op;

const User = UserModel(Sequelize.DataTypes);
const Teacher = TeacherModel(Sequelize.DataTypes);
const Student = StudentModel(Sequelize.DataTypes);
const Section = SectionModel(Sequelize.DataTypes);
const Topic = TopicModel(Sequelize.DataTypes);
const Level = LevelModel(Sequelize.DataTypes);
const Exercise = ExerciseModel(Sequelize.DataTypes);
const MultipleChoices = MultipleChoicesModel(Sequelize.DataTypes);
const MatchingPairs = MatchingPairsModel(Sequelize.DataTypes);
const TrueFalse = TrueFalseModel(Sequelize.DataTypes);
const StdLearning = StdLearningModel(Sequelize.DataTypes);
const StdExercise = StdExerciseModel(Sequelize.DataTypes);
const Class = ClassModel(Sequelize.DataTypes);
const Monitoring = MonitoringModel(Sequelize.DataTypes);
const Report = ReportModel(Sequelize.DataTypes);

User.hasOne(Teacher, { foreignKey: "ID", as: "teachers" });
Teacher.belongsTo(User, { foreignKey: "ID", as: "teacherUser" });

User.hasOne(Student, { foreignKey: "ID", as: "students" });
Student.belongsTo(User, { foreignKey: "ID", as: "studentUser" });

Section.hasMany(Topic, { foreignKey: "ID_SECTION", as: "topics" });
Topic.belongsTo(Section, { foreignKey: "ID_SECTION", as: "topicSection" });

Topic.hasMany(Level, { foreignKey: "ID_TOPIC", as: "levels" });
Level.belongsTo(Topic, { foreignKey: "ID_TOPIC", as: "levelTopic" });

Level.hasMany(Exercise, { foreignKey: "ID_LEVEL", as: "exercises" });
Exercise.belongsTo(Level, { foreignKey: "ID_LEVEL", as: "levelExercise" });

Exercise.hasMany(MultipleChoices, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "multipleChoices",
});
MultipleChoices.belongsTo(Exercise, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "exerciseMultipleChoices",
});

Exercise.hasMany(MatchingPairs, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "matchingPairs",
});
MatchingPairs.belongsTo(Exercise, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "exerciseMatchingPairs",
});

Exercise.hasMany(TrueFalse, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "trueFalse",
});
TrueFalse.belongsTo(Exercise, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "exerciseTrueFalse",
});

User.hasMany(StdLearning, { foreignKey: "ID", as: "userLearning" });
StdLearning.belongsTo(User, { foreignKey: "ID", as: "learningUser" });

Level.hasMany(StdLearning, { foreignKey: "ID_LEVEL", as: "stdLearning" });
StdLearning.belongsTo(Level, { foreignKey: "ID_LEVEL", as: "level" });

Level.hasOne(StdLearning, { foreignKey: "NEXT_LEARNING", as: "nextLevel" });
StdLearning.belongsTo(Level, { foreignKey: "NEXT_LEARNING", as: "nextLevel" });

StdLearning.hasMany(StdExercise, {
  foreignKey: "ID_STUDENT_LEARNING",
  as: "stdExercises",
});
StdExercise.belongsTo(StdLearning, {
  foreignKey: "ID_STUDENT_LEARNING",
  as: "stdLearningExercise",
});

StdExercise.belongsTo(Exercise, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "stdExerciseExercises",
});
Exercise.hasMany(StdExercise, {
  foreignKey: "ID_ADMIN_EXERCISE",
  as: "exerciseStdExercises",
});

Class.hasMany(Student, { foreignKey: "ID_CLASS", as: "ClassStudents" });
Student.belongsTo(Class, { foreignKey: "ID_CLASS", as: "studentClass" });

Monitoring.hasOne(StdLearning, {
  foreignKey: "ID_STUDENT_LEARNING",
  sourceKey: "ID_STUDENT_LEARNING",
  as: "stdLearningMonitoring",
});
StdLearning.belongsTo(Monitoring, {
  foreignKey: "ID_STUDENT_LEARNING",
  as: "monitoringLearning",
});

Monitoring.hasMany(Class, { foreignKey: "ID_CLASS", as: "monitoringClasses" });
Class.belongsTo(Monitoring, { foreignKey: "ID_CLASS", as: "monitoringClass" });

Teacher.hasMany(Monitoring, {
  foreignKey: "ID_GURU",
  as: "teacherMonitorings",
});
Monitoring.belongsTo(Teacher, {
  foreignKey: "ID_GURU",
  as: "monitoringTeacher",
});

User.hasMany(Report, { foreignKey: "ID", as: "userReport" });
Report.belongsTo(User, { foreignKey: "ID", as: "reportUser" });

const models = {
  User,
  Teacher,
  Student,
  Section,
  Topic,
  Level,
  Exercise,
  MultipleChoices,
  MatchingPairs,
  TrueFalse,
  StdLearning,
  StdExercise,
  Class,
  Monitoring,
  Report,
  Sequelize,
  Op,
  db,
};

export default models;
