const { DataTypes } = require("sequelize");

module.exports = (sequelize) => {
  const Territory = sequelize.define(
    "territorie",
    {
      id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      creation: { type: DataTypes.DATE, allowNull: false },
      modified: { type: DataTypes.DATE, allowNull: false },
      modified_by: { type: DataTypes.INTEGER, allowNull: false },
      owner: { type: DataTypes.INTEGER, allowNull: false },
      enabled: { type: DataTypes.BOOLEAN, allowNull: false },

      name: { type: DataTypes.STRING(50), allowNull: false, unique: true },
      display_name: { type: DataTypes.STRING(100), allowNull: true },
      slug_name: { type: DataTypes.STRING(100), allowNull: true },
      description: { type: DataTypes.TEXT, allowNull: true },
      code: { type: DataTypes.STRING(20), allowNull: true },
      type: { type: DataTypes.STRING(20), allowNull: true },
      is_parent: { type: DataTypes.BOOLEAN, allowNull: true },

      // fk
      company_id: {
        type: DataTypes.INTEGER,
        allowNull: true,
        references: {
          model: "companies",
          key: "id",
        },
      },

      // sappsv1 or erpnext
      ids: { type: DataTypes.INTEGER, allowNull: true },
      import_from: { type: DataTypes.STRING(10), allowNull: true },
    },
    {
      tableName: "territories",
      freezeTableName: true,
    }
  );

  /**
   * Associates the Territory model with other models.
   * @param {object} models - The models to associate with.
   * @description
   *   - A Territory belongs to a Company.
   */
  Territory.associate = (models) => {
    /**
     * Associates the Territory model with the Company model.
     * Defines a many-to-one relationship between Territory and Company.
     * @param {object} models - The models to associate with.
     */
    Territory.belongsTo(models.Company, { foreignKey: "company_id", as: "company" });

    /**
     * Associates the Territory model with the TerritoryVersionChild model.
     * A Territory has many TerritoryVersionChilds.
     * @param {object} models - The models to associate with.
     */
    Territory.hasMany(models.TerritoryVersionChild, { foreignKey: "parent_id", as: "territoryversionchilds" });

    // A Territory has many TerritoryVersionChilds.
    // Defines a one-to-many relationship between Territory and TerritoryVersionChild.
    Territory.hasMany(models.TerritoryVersionChild, { foreignKey: "territory_id", as: "territories" });

    /**
     * Associates the Territory model with the Employee model.
     * Defines a many-to-many relationship between Territory and Employee.
     * @param {object} models - The models to associate with.
     */
    Territory.belongsToMany(models.Employee, {
      through: models.EmployeeTerritory,
      foreignKey: "territory_id",
      otherKey: "employee_id",
      as: "employees",
    });

    /**
     * Territory has many EmployeeTerritory (junction table).
     * Allows including employeeterritory rows when querying from Territory.
     */
    Territory.hasMany(models.EmployeeTerritory, {
      foreignKey: "territory_id",
      as: "employeeterritory",
    });

    /**
     * Associates the Territory model with the ItemGroup model.
     * Defines a many-to-many relationship between Territory and ItemGroup.
     * @param {object} models - The models to associate with.
     */
    Territory.belongsToMany(models.ItemGroup, {
      through: models.TerritoryItemGroup,
      foreignKey: "territory_id",
      otherKey: "itemgroup_id",
      as: "itemgroups",
    });

    /**
     * Associates the Territory model with the Outlet model.
     * Defines a many-to-many relationship between Territory and Outlet.
     * @param {object} models - The models to associate with.
     */
    Territory.belongsToMany(models.Outlet, {
      through: models.TerritoryOutlet,
      foreignKey: "territory_id",
      otherKey: "outlet_id",
      as: "outlets",
    });

    // A Territory has many CallPlans.
    // Defines a one-to-many relationship between Territory and CallPlan.
    Territory.hasMany(models.CallPlan, { foreignKey: "territory_id", as: "callplans" });

    // A Territory has many WorkflowApprovers.
    // Defines a one-to-many relationship between Territory and WorkflowApprover.
    Territory.hasMany(models.WorkflowApprover, { foreignKey: "territory_id", as: "workflowapprovers" });

    /**
     * Associates the Territory model with the SalesDistributor model.
     * Defines a one-to-many relationship between Territory and SalesDistributor.
     * @param {object} models - The models to associate with.
     */
    Territory.hasMany(models.SalesDistributor, { foreignKey: "territory_id", as: "salesdistributors" });

    /**
     * A Territory has many MasterList.
     * Defines a one-to-many relationship between Territory and MasterList.
     * @param {object} models - The models to associate with.
     */
    Territory.hasMany(models.MasterList, { foreignKey: "territory_id", as: "masterlist_territories" });

    /**
     * A Territory has many ImportSalesDistributor.
     * Defines a one-to-many relationship between Territory and ImportSalesDistributor.
     * @param {object} models - The models to associate with.
     */
    Territory.hasMany(models.ImportSalesDistributor, { foreignKey: "territory_id", as: "importsalesdistributors" });
    Territory.hasMany(models.ClientCollab, { foreignKey: "territory_id", as: "clientcollabs" });
    Territory.hasMany(models.Survey, { foreignKey: "territory_id", as: "surveys" });
    Territory.hasMany(models.Udp, { foreignKey: "territory_id", as: "udps" });
    Territory.hasMany(models.SalesTarget, { foreignKey: "territory_id", as: "salestargets" });
    Territory.hasMany(models.EmployeeRequest, { foreignKey: "new_territory_id", as: "new_territory" });
    Territory.hasMany(models.SalesPlan, { foreignKey: "territory_id", as: "salesplans" });
    Territory.hasMany(models.Fse, { foreignKey: "territory_id", as: "fses" });
    Territory.hasMany(models.GimmickRequest, { foreignKey: "territory_id", as: "gimmickrequests" });
    Territory.hasMany(models.UpCountry, { foreignKey: "territory_id", as: "upcountries" });
    Territory.hasMany(models.UcCostRealization, { foreignKey: "territory_id", as: "uccostrealizations" });
    Territory.hasMany(models.TerritoryItemGroup, { foreignKey: "territory_id", as: "territoryitemgroups" });
  };

  return Territory;
};
