import { DataTypes, Model, Optional } from "sequelize";
import Joi from "joi";
import sequelize from "../middlewears/sequelize";
import { SessionModel } from "./session";
import { ClassModel } from "./class";

// TypeScript interfaces for the nested objects
export interface IUpperWearDetails {
  collar: string;
  cuff: string;
  tera: string;
  bazo: string;
  armhole: string;
  chest: string;
  bokramUsed?: string;
  collarUsed?: string;
  buttonUsed?: string;
  fabricUsed: string;
  upperWearPrice: string;
}

export interface ILowerWearDetails {
  losign: string;
  hip: string;
  waist: string;
  bottom: string;
  zipUsed?: string;
  buttonUsed?: string;
  hookUsed?: string;
  fabricUsed: string;
  lowerWearPrice: string;
}

export interface IHeadCoverDetails {
  type: string;
  length: string;
  fabricUsed: string;
  headCoverPrice: string;
}

export interface IStudent {
  id: number;
  sessionId: number;
  name: string;
  gender: string;
  sizeNumber: string;
  upperWear: IUpperWearDetails;
  lowerWear: ILowerWearDetails;
  headcover: IHeadCoverDetails | null;
  isDeleted: boolean;
  createdAt?: Date;
  updatedAt?: Date;
}

interface IStudentAttributes
  extends Optional<IStudent, "id" | "isDeleted" | "createdAt" | "updatedAt"> {}

class StudentModel
  extends Model<IStudent, IStudentAttributes>
  implements IStudent
{
  id!: number;
  sessionId!: number;
  name!: string;
  gender!: string;
  sizeNumber!: string;
  upperWear!: IUpperWearDetails;
  lowerWear!: ILowerWearDetails;
  headcover!: IHeadCoverDetails | null;
  isDeleted!: boolean;
  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;
}

StudentModel.init(
  {
    id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true },
    sessionId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: { model: "sessions", key: "id" },
    },
    name: { type: DataTypes.STRING, allowNull: false },
    gender: { type: DataTypes.STRING, allowNull: false },
    sizeNumber: { type: DataTypes.STRING, allowNull: false },
    upperWear: {
      type: DataTypes.JSON, // Storing object as JSON in the database
      allowNull: false,
    },
    lowerWear: {
      type: DataTypes.JSON, // Storing object as JSON in the database
      allowNull: false,
    },
    headcover: {
      type: DataTypes.JSON, // Storing object as JSON in the database
      allowNull: true,
    },
    isDeleted: {
      type: DataTypes.BOOLEAN,
      allowNull: true,
      defaultValue: false,
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
    },
  },
  {
    sequelize,
    tableName: "students",
  }
);

const studentValidationSchema = Joi.object({
  sessionId: Joi.number().integer().required(),
  name: Joi.string().min(1).max(255).required(),
  gender: Joi.string().valid("male", "female").required(),
  sizeNumber: Joi.string().min(1).max(50).required(),
  upperWear: Joi.object({
    collar: Joi.string().required(),
    cuff: Joi.string().required(),
    tera: Joi.string().required(),
    bazo: Joi.string().required(),
    armhole: Joi.string().required(),
    chest: Joi.string().required(),
    bokramUsed: Joi.string().optional(),
    collarUsed: Joi.string().optional(),
    buttonUsed: Joi.string().optional(),
    fabricUsed: Joi.string().required(),
    upperWearPrice: Joi.string().required(),
  }).required(),
  lowerWear: Joi.object({
    losign: Joi.string().required(),
    hip: Joi.string().required(),
    waist: Joi.string().required(),
    bottom: Joi.string().required(),
    zipUsed: Joi.string().optional(),
    buttonUsed: Joi.string().optional(),
    hookUsed: Joi.string().optional(),
    fabricUsed: Joi.string().required(),
    lowerWearPrice: Joi.string().required(),
  }).required(),
  headcover: Joi.object({
    type: Joi.string().required(),
    length: Joi.string().required(),
    fabricUsed: Joi.string().required(),
    headCoverPrice: Joi.string().required(),
  }).when("gender", {
    is: "female",
    then: Joi.optional(),
    otherwise: Joi.forbidden(),
  }),
  isDeleted: Joi.boolean().optional(),
});

const updateStudentValidationSchema = Joi.object({
  sessionId: Joi.number().integer().optional(),
  name: Joi.string().min(1).max(255).optional(),
  gender: Joi.string().valid("male", "female").optional(),
  sizeNumber: Joi.string().min(1).max(50).optional(),
  upperWear: Joi.object({
    collar: Joi.string().optional(),
    cuff: Joi.string().optional(),
    tera: Joi.string().optional(),
    bazo: Joi.string().optional(),
    armhole: Joi.string().optional(),
    chest: Joi.string().optional(),
    bokramUsed: Joi.string().optional(),
    collarUsed: Joi.string().optional(),
    buttonUsed: Joi.string().optional(),
    fabricUsed: Joi.string().optional(),
    upperWearPrice: Joi.string().optional(),
  }).optional(),
  lowerWear: Joi.object({
    losign: Joi.string().optional(),
    hip: Joi.string().optional(),
    waist: Joi.string().optional(),
    bottom: Joi.string().optional(),
    zipUsed: Joi.string().optional(),
    buttonUsed: Joi.string().optional(),
    hookUsed: Joi.string().optional(),
    fabricUsed: Joi.string().optional(),
    lowerWearPrice: Joi.string().optional(),
  }).optional(),
  headcover: Joi.object({
    type: Joi.string().optional(),
    length: Joi.string().optional(),
    fabricUsed: Joi.string().optional(),
    headCoverPrice: Joi.string().optional(),
  }).when("gender", {
    is: "female",
    then: Joi.optional(),
    otherwise: Joi.forbidden(),
  }),
  isDeleted: Joi.boolean().optional(),
});

// Associations are defined in associations.ts to avoid circular imports

export { StudentModel, studentValidationSchema, updateStudentValidationSchema };
