import {
  DataTypes,
  InferAttributes,
  InferCreationAttributes,
  Model,
  Op,
  Sequelize,
} from "sequelize";

export enum USER_ROLES {
  ROLE_ADMIN = "ROLE_ADMIN",
  ROLE_USER = "ROLE_USER",
}

export type UserCreationAttributes = InferCreationAttributes<User_Model>;

export class User_Model extends Model<
  InferAttributes<User_Model>,
  InferCreationAttributes<User_Model>
> {
  // To avoid table creation
  /*static async sync(): Promise<any> {
      return Promise.resolve();
    }*/

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  static associate(connection: Sequelize) {
    const { User_Model, Dealer_Model } = connection.models;

    User_Model.hasOne(Dealer_Model, {
      as: "dealer",
      foreignKey: "user_id",
      onDelete: "RESTRICT",
    });
  }

  declare id: string;
  declare name: string;
  declare email: string;
  declare password: string;
  declare lang_code: string;
  declare roles: string[];
}

export default (sequelize: Sequelize) => {
  User_Model.init(
    {
      id: {
        type: new DataTypes.UUID(),
        primaryKey: true,
      },

      name: {
        type: DataTypes.STRING,
      },

      email: {
        type: DataTypes.STRING,
        allowNull: false,
      },

      password: {
        type: DataTypes.STRING,
        allowNull: false,
      },

      lang_code: {
        type: DataTypes.STRING(2),
        allowNull: false,
        defaultValue: "es",
      },

      roles: {
        type: DataTypes.STRING,
        allowNull: false,
        defaultValue: USER_ROLES.ROLE_USER,
        get(this: User_Model): string[] {
          const rawValue = this.getDataValue("roles") as any;
          return String(rawValue).split(";");
        },
        set(this: User_Model, value: string[]) {
          const rawValue = value.join(";") as any;
          this.setDataValue("roles", rawValue);
        },
      },
    },
    {
      sequelize,
      tableName: "users",

      paranoid: true, // softs deletes
      timestamps: true,
      //version: true,

      createdAt: "created_at",
      updatedAt: "updated_at",
      deletedAt: "deleted_at",

      indexes: [{ name: "email_idx", fields: ["email"], unique: true }],

      whereMergeStrategy: "and", // <- cómo tratar el merge de un scope
      scopes: {
        quickSearch(value) {
          return {
            where: {
              [Op.or]: {
                name: {
                  [Op.like]: `%${value}%`,
                },
                email: {
                  [Op.like]: `%${value}%`,
                },
              },
            },
          };
        },
      },
    }
  );

  return User_Model;
};
