
import dayjs from "dayjs";
import {
    FindPlanSuscripcionsParams,
    IPlanSuscriptionsAdapter,
    IPlanSuscription,
    CreatePlanSuscriptionParams,
    CancellPlanSuscriptionParams,
} from "./PlanSubscriptions.interface";
import { Document, Model, Schema, model } from "mongoose";

export interface IPlanSuscriptionDocument extends Omit<IPlanSuscription, "id">, Document {}

export enum MP_SUBS_STATUS {
    PENDING = "pending",
    AUTHORIZED = "authorized",
    PAUSED = "paused",
    CANCELLED = "cancelled",
}

export class PlanSuscriptionsAdapterMongoose implements IPlanSuscriptionsAdapter {
    schema: Schema;
    planSuscriptionList: Model<IPlanSuscriptionDocument>;

    constructor() {
        this.schema = new Schema({
            userId: { type: Schema.Types.ObjectId, required: true, ref: "User" },
            planId: { type: Schema.Types.ObjectId, required: true, ref: "Plan" },
            mpPlanId: { type: String, required: false },
            startDate: { type: Date, required: true },
            endDate: { type: Date, required: true },
            isActive: { type: Boolean, required: true, default: true },
            autoRenew: { type: Boolean, required: true, default: true },
            paymentMethod: { type: String, required: false },
            mpPayerId: { type: Number, required: false },
            mpPayerEmail: { type: String, required: false },
            mpStatus: { type: String, required: false },
            mpDateCreated: { type: Date, required: false },
            mpInitPoint: { type: String, required: false },
            mpPreferenceId: { type: String, required: false },
        });

        this.planSuscriptionList = model<IPlanSuscriptionDocument>("PlanSuscription", this.schema);
    }

    public async find(filters: FindPlanSuscripcionsParams): Promise<IPlanSuscription[]> {
        return this.planSuscriptionList.find(filters).exec();
    }

    public async delete(data: CancellPlanSuscriptionParams): Promise<void> {
        await this.planSuscriptionList.deleteOne({ userId: data.sessionUser }).exec();
    }

    public async findOne(
        filters: FindPlanSuscripcionsParams
    ): Promise<IPlanSuscriptionDocument | null> {
        let subscription = await this.planSuscriptionList
            .findOne({ userId: filters.sessionUser })
            .exec();

        if (!subscription) {
            return null;
        }

        const dateNow = dayjs(new Date());
        const dateEnd = dayjs(subscription.endDate);

        try {
            if (subscription.mpPreferenceId) {
                if (dateNow.isAfter(dateEnd)) {
                    if (subscription.mpStatus == MP_SUBS_STATUS.CANCELLED) {
                        subscription.mpPreferenceId = "";
                        subscription.isActive = false;
                        subscription.autoRenew = false;
                        subscription.mpStatus = MP_SUBS_STATUS.CANCELLED;
                        subscription.mpInitPoint = "";
                        await subscription.save();
                        return subscription;
                    }
                    // Without subscriptions, we wait for the webhook to update the status.
                    // If it's expired and not updated by webhook, we just cancel it.
                    if (subscription.mpStatus === MP_SUBS_STATUS.PENDING) {
                        subscription.mpPreferenceId = "";
                        subscription.isActive = false;
                        subscription.autoRenew = false;
                        subscription.mpStatus = MP_SUBS_STATUS.CANCELLED;
                        subscription.mpInitPoint = "";
                        await subscription.save();
                        return subscription;
                    }
                }
            }
        } catch (e) {
            console.log("Ha ocurrido un error al revisar el estado de la suscripcion:", e);
        }

        return subscription;
    }

    // updateMpStatus was removed as it relied on MercadoPago Subscriptions API.
    // Payments status updates are now handled by the WebhookController.

    public async create(data: CreatePlanSuscriptionParams): Promise<IPlanSuscriptionDocument> {
        return await this.planSuscriptionList.create(data);
    }
}
