import * as Sequelize from 'sequelize';
import { Op } from 'sequelize';
import { DataTypes, Model, Optional } from 'sequelize';
import type { BillItem, BillItemId } from './BillItem';
export interface BillAttributes {
	id: string;
	code: string;
	room_id: string;
	resident_id: string;
	billing_period: string;
	due_date: string;
	payment_method?: string | null;
	notes?: string | null;
	total_amount?: number | null;
	status: string;
	created_by?: string | null;
	created_at?: Date | null;
	updated_at?: Date | null;
	deleted_by?: string | null;
	deleted_at?: Date | null;
}
export type BillPk = 'id';
export type BillId = Bill[BillPk];
export type BillOptionalAttributes =
	| 'id'
	| 'payment_method'
	| 'notes'
	| 'total_amount'
	| 'status'
	| 'created_by'
	| 'created_at'
	| 'updated_at'
	| 'deleted_by'
	| 'deleted_at';
export type BillCreationAttributes = Optional<BillAttributes, BillOptionalAttributes>;
export class Bill extends Model<BillAttributes> implements BillAttributes {
	declare id: string;
	declare code: string;
	declare room_id: string;
	declare resident_id: string;
	declare billing_period: string;
	declare due_date: string;
	declare payment_method?: string | null;
	declare notes?: string | null;
	declare total_amount?: number | null;
	declare status: string;
	declare created_by?: string | null;
	declare created_at?: Date | null;
	declare updated_at?: Date | null;
	declare deleted_by?: string | null;
	declare deleted_at?: Date | null;
	// Bill hasMany BillItem via bill_id
	declare bill_items: BillItem[];
	declare getBill_items: Sequelize.HasManyGetAssociationsMixin<BillItem>;
	declare setBill_items: Sequelize.HasManySetAssociationsMixin<BillItem, BillItemId>;
	declare addBill_item: Sequelize.HasManyAddAssociationMixin<BillItem, BillItemId>;
	declare addBill_items: Sequelize.HasManyAddAssociationsMixin<BillItem, BillItemId>;
	declare createBill_item: Sequelize.HasManyCreateAssociationMixin<BillItem>;
	declare removeBill_item: Sequelize.HasManyRemoveAssociationMixin<BillItem, BillItemId>;
	declare removeBill_items: Sequelize.HasManyRemoveAssociationsMixin<BillItem, BillItemId>;
	declare hasBill_item: Sequelize.HasManyHasAssociationMixin<BillItem, BillItemId>;
	declare hasBill_items: Sequelize.HasManyHasAssociationsMixin<BillItem, BillItemId>;
	declare countBill_items: Sequelize.HasManyCountAssociationsMixin;
	static initModel(sequelize: Sequelize.Sequelize): typeof Bill {
		return Bill.init(
			{
				id: {
					type: DataTypes.UUID,
					allowNull: false,
					defaultValue: DataTypes.UUIDV4,
					primaryKey: true,
				},
				code: {
					type: DataTypes.STRING(50),
					allowNull: false,
					unique: 'bills_code_key',
				},
				room_id: {
					type: DataTypes.UUID,
					allowNull: false,
				},
				resident_id: {
					type: DataTypes.UUID,
					allowNull: false,
				},
				billing_period: {
					type: DataTypes.STRING(7),
					allowNull: false,
				},
				due_date: {
					type: DataTypes.DATEONLY,
					allowNull: false,
				},
				payment_method: {
					type: DataTypes.STRING(50),
					allowNull: true,
				},
				notes: {
					type: DataTypes.TEXT,
					allowNull: true,
				},
				total_amount: {
					type: DataTypes.DECIMAL,
					allowNull: true,
					defaultValue: 0,
				},
				status: {
					type: DataTypes.STRING(20),
					allowNull: false,
					defaultValue: 'pending',
				},
				created_by: {
					type: DataTypes.UUID,
					allowNull: true,
				},
				created_at: {
					type: DataTypes.DATE,
					allowNull: true,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
				updated_at: {
					type: DataTypes.DATE,
					allowNull: true,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
				deleted_by: {
					type: DataTypes.UUID,
					allowNull: true,
				},
				deleted_at: {
					type: DataTypes.DATE,
					allowNull: true,
				},
			},
			{
				sequelize,
				tableName: 'bills',
				schema: 'public',
				timestamps: false,

				scopes: {
					default: {
						where: {
							deleted_at: null,
						},
					},
					withDeleted: {},
					onlyDeleted: {
						where: {
							deleted_at: { [Op.ne]: null },
						},
					},
				},
				indexes: [
					{
						name: 'bills_code_key',
						unique: true,
						fields: [{ name: 'code' }],
					},
					{
						name: 'bills_pkey',
						unique: true,
						fields: [{ name: 'id' }],
					},
					{
						name: 'idx_bills_billing_period',
						fields: [{ name: 'billing_period' }],
					},
					{
						name: 'idx_bills_deleted_at',
						fields: [{ name: 'deleted_at' }],
					},
					{
						name: 'idx_bills_resident_id',
						fields: [{ name: 'resident_id' }],
					},
					{
						name: 'idx_bills_room_id',
						fields: [{ name: 'room_id' }],
					},
					{
						name: 'idx_bills_status_due_date',
						fields: [{ name: 'status' }, { name: 'due_date' }],
					},
				],
			},
		);
	}
}
