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

import { ContactAddress_Model, TCreationContactAddress_Attributes } from "./contactAddress.mo.del";

export type TCreationContact_Model = InferCreationAttributes<
  Contact_Model,
  { omit: "shippingAddress" | "billingAddress" }
> & {
  billingAddress: TCreationContactAddress_Attributes;
  shippingAddress: TCreationContactAddress_Attributes;
};

export class Contact_Model extends Model<
  InferAttributes<Contact_Model, { omit: "shippingAddress" | "billingAddress" }>,
  InferCreationAttributes<Contact_Model, { omit: "shippingAddress" | "billingAddress" }>
> {
  // To avoid table creation
  static async sync(): Promise<any> {
    return Promise.resolve();
  }

  static associate(connection: Sequelize) {
    const { Contact_Model, ContactAddress_Model } = connection.models;

    Contact_Model.hasOne(ContactAddress_Model, {
      as: "shippingAddress",
      foreignKey: "customer_id",
      onDelete: "CASCADE",
    });

    Contact_Model.hasOne(ContactAddress_Model, {
      as: "billingAddress",
      foreignKey: "customer_id",
      onDelete: "CASCADE",
    });
  }

  declare id: string;
  declare tin: CreationOptional<string>;
  declare company_name: CreationOptional<string>;
  declare first_name: CreationOptional<string>;
  declare last_name: CreationOptional<string>;

  declare shippingAddress?: NonAttribute<ContactAddress_Model>;
  declare billingAddress?: NonAttribute<ContactAddress_Model>;
}

export default (sequelize: Sequelize) => {
  Contact_Model.init(
    {
      id: {
        type: new DataTypes.UUID(),
        primaryKey: true,
      },
      tin: {
        type: new DataTypes.STRING(),
      },
      company_name: {
        type: new DataTypes.STRING(),
      },
      first_name: {
        type: new DataTypes.STRING(),
      },
      last_name: {
        type: new DataTypes.STRING(),
      },
    },
    {
      sequelize,
      tableName: "customers",
      timestamps: false,
    }
  );

  return Contact_Model;
};
