"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSubscriptionsController = createSubscriptionsController;
const types_js_1 = require("../../domain/subscriptions/types.js");
const AdminPinService_js_1 = require("../../infrastructure/auth/AdminPinService.js");
const SubscriptionModel_js_1 = require("../../infrastructure/database/models/SubscriptionModel.js");
const STATUS_VALUES = ["active", "expired", "revoked"];
const LEGACY_PLAN_VALUES = ["monthly", "yearly", "lifetime"];
const PLAN_VALUES = [...types_js_1.PAYMENT_PLANS.map((plan) => plan.code), ...LEGACY_PLAN_VALUES];
const toSubscriptionResponse = (sub) => ({
    id: sub._id.toString(),
    telegramId: sub.telegramId,
    username: sub.username,
    platformCode: sub.platformCode,
    selectedPlan: sub.selectedPlan,
    status: sub.status,
    subscriptionStart: sub.subscriptionStart.toISOString(),
    subscriptionEnd: sub.subscriptionEnd?.toISOString(),
    isLifetime: sub.isLifetime,
    lastPaymentId: sub.lastPaymentId?.toString(),
    createdAt: sub.createdAt.toISOString(),
    updatedAt: sub.updatedAt.toISOString()
});
function createSubscriptionsController(_config) {
    return {
        list: async (req, res) => {
            const { status, plan, search, limit = "50", offset = "0" } = req.query;
            const filter = {};
            if (status) {
                filter.status = status;
            }
            if (plan) {
                filter.selectedPlan = plan;
            }
            if (search?.trim()) {
                const term = search.trim();
                filter.$or = [
                    { telegramId: { $regex: term, $options: "i" } },
                    { username: { $regex: term, $options: "i" } }
                ];
            }
            const [data, total] = await Promise.all([
                SubscriptionModel_js_1.SubscriptionModel.find(filter)
                    .sort({ updatedAt: -1 })
                    .skip(Number(offset ?? "0"))
                    .limit(Number(limit ?? "50"))
                    .lean(),
                SubscriptionModel_js_1.SubscriptionModel.countDocuments(filter)
            ]);
            res.json({
                data: data.map(toSubscriptionResponse),
                total
            });
        },
        getById: async (req, res) => {
            const sub = await SubscriptionModel_js_1.SubscriptionModel.findById(req.params.id).lean();
            if (!sub) {
                res.status(404).json({ error: "Subscription not found." });
                return;
            }
            res.json({ data: toSubscriptionResponse(sub) });
        },
        update: async (req, res) => {
            const { adminKey, status, selectedPlan, subscriptionEnd, isLifetime } = req.body;
            const isValidPin = adminKey ? await AdminPinService_js_1.AdminPinService.verifyPin(adminKey) : false;
            if (!isValidPin) {
                res.status(403).json({ error: "Invalid admin PIN." });
                return;
            }
            if (status && !STATUS_VALUES.includes(status)) {
                res.status(400).json({ error: "Invalid status." });
                return;
            }
            if (selectedPlan && !PLAN_VALUES.includes(selectedPlan)) {
                res.status(400).json({ error: "Invalid plan." });
                return;
            }
            const update = {};
            if (status)
                update.status = status;
            if (selectedPlan) {
                update.selectedPlan = selectedPlan;
                const plan = (0, types_js_1.getPaymentPlan)(selectedPlan);
                if (plan) {
                    update.platformCode = plan.platformCode;
                }
            }
            if (subscriptionEnd !== undefined) {
                update.subscriptionEnd = subscriptionEnd ? new Date(subscriptionEnd) : null;
            }
            if (typeof isLifetime === "boolean") {
                update.isLifetime = isLifetime;
                if (isLifetime) {
                    update.subscriptionEnd = null;
                }
            }
            if (Object.keys(update).length === 0) {
                res.status(400).json({ error: "No fields provided to update." });
                return;
            }
            const sub = await SubscriptionModel_js_1.SubscriptionModel.findByIdAndUpdate(req.params.id, { $set: update }, { new: true, runValidators: true }).lean();
            if (!sub) {
                res.status(404).json({ error: "Subscription not found." });
                return;
            }
            res.json({ data: toSubscriptionResponse(sub) });
        },
        delete: async (req, res) => {
            const { adminKey } = req.body;
            const isValidPin = adminKey ? await AdminPinService_js_1.AdminPinService.verifyPin(adminKey) : false;
            if (!isValidPin) {
                res.status(403).json({ error: "Invalid admin PIN." });
                return;
            }
            const sub = await SubscriptionModel_js_1.SubscriptionModel.findByIdAndDelete(req.params.id).lean();
            if (!sub) {
                res.status(404).json({ error: "Subscription not found." });
                return;
            }
            res.json({ success: true });
        }
    };
}
