import { Document, Model, Schema, model, FilterQuery } from "mongoose";
import {
    CreateCashFlowBalanceParams,
    FindCashFlowBalanceParams,
    ICashFlowBalance,
    ICashFlowBalanceAdapter,
} from "./CashFlowBalance.Interface";

export interface ICashFlowBalanceDocument extends Omit<ICashFlowBalance, "id">, Document {}

export class CashFlowBalanceAdapterMongoose implements ICashFlowBalanceAdapter {
    schema: Schema;
    balanceList: Model<ICashFlowBalanceDocument>;

    constructor() {
        this.schema = new Schema({
            companyId: {
                type: Schema.Types.ObjectId,
                required: true,
                ref: "Company",
            },
            amount: { type: Number, required: true, default: 0 },
            year: { type: Number, required: true, default: 0 },
            month: { type: Number, required: true, default: 0 },
            updatedAt: { type: Date, required: true, default: Date.now },
        });

        this.balanceList = model<ICashFlowBalanceDocument>("CashFlowBalance", this.schema);
    }

    public async create(data: CreateCashFlowBalanceParams): Promise<ICashFlowBalance> {
        return await this.balanceList.create(data);
    }

    public async delete(id: string): Promise<void> {
        await this.balanceList.deleteOne({ _id: id });
    }

    private buildSearchCriteria(
        filters: Omit<FindCashFlowBalanceParams, "sessionUser">
    ): FilterQuery<ICashFlowBalance> {
        const searchCriteria: FilterQuery<ICashFlowBalance> = {};

        if (filters.companyId) {
            searchCriteria.companyId = filters.companyId;
        }

        if (filters.month) {
            searchCriteria.month = filters.month;
        }

        if (filters.year) {
            searchCriteria.year = filters.year;
        }

        return searchCriteria;
    }

    public async find(
        filters: Omit<FindCashFlowBalanceParams, "sessionUser">
    ): Promise<ICashFlowBalance[]> {
        const searchCriteria = this.buildSearchCriteria(filters);
        return this.balanceList.find(searchCriteria).exec();
    }

    public async findOne(
        filters: Omit<FindCashFlowBalanceParams, "sessionUser">
    ): Promise<ICashFlowBalanceDocument | null> {
        return this.balanceList.findOne(filters).exec();
    }
}
