"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PackagePurchaseController = void 0;
const tslib_1 = require("tslib");
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable @typescript-eslint/no-explicit-any */
const repository_1 = require("@loopback/repository");
const rest_1 = require("@loopback/rest");
const models_1 = require("../models");
const repositories_1 = require("../repositories");
const core_1 = require("@loopback/core");
const rest_2 = require("@loopback/rest");
// PhonePe Configuration
const PHONEPE_CONFIG = {
    merchantId: "MERCHANTUAT",
    saltKey: "099eb0cd-02cf-4e2a-8aca-3e6c6aff0399",
    saltIndex: "1",
    apiEndpoint: "https://api-preprod.phonepe.com/apis/pg-sandbox",
};
let PackagePurchaseController = class PackagePurchaseController {
    constructor(packagePurchaseRepository, request) {
        this.packagePurchaseRepository = packagePurchaseRepository;
        this.request = request;
    }
    /**
     * Verify PhonePe payment and create package purchase
     */
    // @post('/package-purchases/verify-payment')
    // @response(200, {
    //   description: 'Verify PhonePe payment and create package purchase',
    //   content: {'application/json': {schema: getModelSchemaRef(PackagePurchase)}},
    // })
    // async verifyPayment(
    //   @requestBody({
    //     content: {
    //       'application/json': {
    //         schema: {
    //           type: 'object',
    //           required: ['transactionId', 'packageId', 'userId', 'amount'],
    //           properties: {
    //             transactionId: {type: 'string'},
    //             packageId: {type: 'number'},
    //             userId: {type: 'number'},
    //             amount: {type: 'number'},
    //             packageDuration: {type: 'number'},
    //             propertyVisit: {type: 'number'},
    //             propertyAddToCart: {type: 'number'},
    //             usertypeId: {type: 'number'},
    //           },
    //         },
    //       },
    //     },
    //   })
    //   paymentData: {
    //     transactionId: string;
    //     packageId: number;
    //     userId: number;
    //     amount: number;
    //     packageDuration?: number;
    //     propertyVisit?: number;
    //     propertyAddToCart?: number;
    //     usertypeId?: number;
    //   },
    // ): Promise<PackagePurchase> {
    //   try {
    //     console.log('=== Backend: Verifying Payment ===');
    //     console.log('Payment Data:', paymentData);
    //     // Check if transaction already exists
    //     const existingPurchase = await this.packagePurchaseRepository.findOne({
    //       where: {paymentNo: paymentData.transactionId},
    //     });
    //     if (existingPurchase) {
    //       console.log('Transaction already processed:', paymentData.transactionId);
    //       throw new HttpErrors.BadRequest('Transaction already processed');
    //     }
    //     // Verify payment with PhonePe API
    //     console.log('Verifying with PhonePe API...');
    //     const paymentStatus = await this.verifyPhonePePayment(paymentData.transactionId);
    //     console.log('PhonePe Verification Result:', paymentStatus);
    //     if (!paymentStatus.success) {
    //       throw new HttpErrors.BadRequest(
    //         `Payment verification failed: ${paymentStatus.error || 'Unknown error'}`,
    //       );
    //     }
    //     if (paymentStatus.status !== 'COMPLETED' && paymentStatus.status !== 'SUCCESS') {
    //       throw new HttpErrors.BadRequest(
    //         `Payment is not completed. Current status: ${paymentStatus.status}`,
    //       );
    //     }
    //     // Verify amount matches
    //     const expectedAmount = Math.round(paymentData.amount * 100); // Convert to paise
    //     const actualAmount = paymentStatus.amount;
    //     console.log(`Amount verification - Expected: ${expectedAmount}, Actual: ${actualAmount}`);
    //     if (Math.abs(expectedAmount - actualAmount) > 1) {
    //       // Allow 1 paise difference for rounding
    //       throw new HttpErrors.BadRequest(
    //         `Amount mismatch. Expected: ₹${paymentData.amount}, Got: ₹${actualAmount / 100}`,
    //       );
    //     }
    //     // Calculate dates
    //     const currentDate = new Date();
    //     const packageEndDate = new Date();
    //     packageEndDate.setDate(currentDate.getDate() + (paymentData.packageDuration ?? 30));
    //     console.log('Creating package purchase record...');
    //     // Create package purchase record
    //     const packagePurchase = await this.packagePurchaseRepository.create({
    //       fkPackageId: paymentData.packageId,
    //       fkBuyerIdSellerId: paymentData.userId,
    //       fkUsertypeId: paymentData.usertypeId ?? 1,
    //       date: currentDate.toISOString().split('T')[0], // YYYY-MM-DD
    //       time: currentDate.toTimeString().split(' ')[0], // HH:MM:SS
    //       paymentFag: 1, // 1 for PhonePe
    //       paymentNo: paymentData.transactionId,
    //       paymentAmount: paymentData.amount,
    //       propertyVisit: paymentData.propertyVisit ?? 0,
    //       propertyAddToCart: paymentData.propertyAddToCart ?? 0,
    //       packageEndDate: packageEndDate.toISOString().split('T')[0],
    //       isDefault: 0,
    //       isOn: 1,
    //       isActive: 1,
    //       createdDate: currentDate.toISOString(),
    //       createdBy: paymentData.userId,
    //       lastChanged: currentDate.toISOString(),
    //     });
    //     console.log('Package purchase created:', packagePurchase.packagePurchaseId);
    //     return packagePurchase;
    //   } catch (error) {
    //     console.error('=== Backend: Payment Verification Error ===');
    //     console.error('Error:', error);
    //     if (error instanceof HttpErrors.HttpError) {
    //       throw error;
    //     }
    //     throw new HttpErrors.InternalServerError(
    //       `Failed to verify payment: ${error.message}`,
    //     );
    //   }
    // }
    // Backend Controller Update for DEMO MODE
    // Add this to your package-purchase.controller.ts
    // Update the verifyPayment function to handle demo mode:
    // src/controllers/package-purchase.controller.ts - 修改 verifyPayment 方法
    async verifyPayment(paymentData) {
        var _a, _b, _c, _d, _e;
        try {
            console.log('=== Backend: Package Purchase Creation ===');
            console.log('Payment Data:', paymentData);
            // 检查是否为演示模式
            const isDemoMode = paymentData.isDemoMode || ((_a = paymentData.transactionId) === null || _a === void 0 ? void 0 : _a.startsWith('DEMO'));
            if (isDemoMode) {
                console.log('⚠️ DEMO MODE DETECTED - Skipping PhonePe verification');
            }
            // 更严格地检查交易是否已存在
            const existingPurchase = await this.packagePurchaseRepository.findOne({
                where: { paymentNo: paymentData.transactionId }
            });
            if (existingPurchase) {
                console.log('Transaction already exists:', paymentData.transactionId);
                // 对于演示模式，返回现有购买记录而不是错误
                if (isDemoMode) {
                    console.log('Demo mode: Returning existing purchase');
                    return existingPurchase;
                }
                // 对于真实支付，返回错误
                throw new rest_1.HttpErrors.BadRequest('Transaction already processed');
            }
            // 检查同一用户是否在短时间内购买了相同的套餐
            // 这可以防止由于网络延迟等原因导致的重复提交
            const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
            const recentPurchase = await this.packagePurchaseRepository.findOne({
                where: {
                    and: [
                        { fkBuyerIdSellerId: paymentData.userId },
                        { fkPackageId: paymentData.packageId },
                        { createdDate: { gt: fiveMinutesAgo.toISOString() } }
                    ]
                }
            });
            if (recentPurchase) {
                console.log('Recent similar purchase found:', recentPurchase.packagePurchaseId);
                // 对于演示模式，返回最近的购买记录
                if (isDemoMode) {
                    console.log('Demo mode: Returning recent purchase');
                    return recentPurchase;
                }
                // 对于真实支付，返回错误
                throw new rest_1.HttpErrors.BadRequest('A similar purchase was made recently. Please wait before trying again.');
            }
            // 只有在非演示模式下才验证 PhonePe
            if (!isDemoMode) {
                console.log('Verifying with PhonePe API...');
                const paymentStatus = await this.verifyPhonePePayment(paymentData.transactionId);
                console.log('PhonePe Verification Result:', paymentStatus);
                if (!paymentStatus.success) {
                    throw new rest_1.HttpErrors.BadRequest(`Payment verification failed: ${paymentStatus.error || 'Unknown error'}`);
                }
                if (paymentStatus.status !== 'COMPLETED' && paymentStatus.status !== 'SUCCESS') {
                    throw new rest_1.HttpErrors.BadRequest(`Payment not completed. Status: ${paymentStatus.status}`);
                }
                // 验证真实支付的金额
                const expectedAmount = Math.round(paymentData.amount * 100);
                const actualAmount = paymentStatus.amount;
                if (Math.abs(expectedAmount - actualAmount) > 1) {
                    throw new rest_1.HttpErrors.BadRequest(`Amount mismatch. Expected: ₹${paymentData.amount}, Got: ₹${actualAmount / 100}`);
                }
            }
            else {
                console.log('✅ Demo mode: Skipping PhonePe verification');
            }
            // 计算日期
            const currentDate = new Date();
            const packageEndDate = new Date();
            packageEndDate.setDate(currentDate.getDate() + ((_b = paymentData.packageDuration) !== null && _b !== void 0 ? _b : 30));
            console.log('Creating package purchase record...');
            // 创建套餐购买记录
            const packagePurchase = await this.packagePurchaseRepository.create({
                fkPackageId: paymentData.packageId,
                fkBuyerIdSellerId: paymentData.userId,
                fkUsertypeId: (_c = paymentData.usertypeId) !== null && _c !== void 0 ? _c : 1,
                date: currentDate.toISOString().split('T')[0],
                time: currentDate.toTimeString().split(' ')[0],
                paymentFag: isDemoMode ? 0 : 1,
                paymentNo: paymentData.transactionId,
                paymentAmount: paymentData.amount,
                propertyVisit: (_d = paymentData.propertyVisit) !== null && _d !== void 0 ? _d : 0,
                propertyAddToCart: (_e = paymentData.propertyAddToCart) !== null && _e !== void 0 ? _e : 0,
                packageEndDate: packageEndDate.toISOString().split('T')[0],
                isDefault: 0,
                isOn: 1,
                isActive: 1,
                createdDate: currentDate.toISOString(),
                createdBy: paymentData.userId,
                lastChanged: currentDate.toISOString(),
            });
            console.log('✅ Package purchase created:', packagePurchase.packagePurchaseId);
            if (isDemoMode) {
                console.log('⚠️ DEMO PURCHASE - Payment flag set to 0');
            }
            return packagePurchase;
        }
        catch (error) {
            console.error('=== Backend: Package Purchase Error ===');
            console.error('Error:', error);
            if (error instanceof rest_1.HttpErrors.HttpError) {
                throw error;
            }
            throw new rest_1.HttpErrors.InternalServerError(`Failed to create package purchase: ${error.message}`);
        }
    }
    /**
     * PhonePe callback endpoint
     */
    async handleCallback() {
        try {
            const body = this.request.body;
            console.log('=== PhonePe Callback Received ===');
            console.log('Callback Body:', JSON.stringify(body, null, 2));
            // Decode base64 response if present
            if (body && body.response) {
                try {
                    const decodedResponse = Buffer.from(body.response, 'base64').toString('utf-8');
                    console.log('Decoded Response:', decodedResponse);
                    const responseData = JSON.parse(decodedResponse);
                    console.log('Response Data:', responseData);
                }
                catch (decodeError) {
                    console.error('Failed to decode response:', decodeError);
                }
            }
            return { success: true, message: 'Callback received and logged' };
        }
        catch (error) {
            console.error('=== Callback Error ===');
            console.error('Error:', error);
            return { success: false, message: 'Callback processing failed' };
        }
    }
    /**
     * Helper method to verify payment with PhonePe API
     */
    async verifyPhonePePayment(transactionId) {
        var _a, _b;
        try {
            const crypto = require('crypto');
            const axios = require('axios');
            console.log('Verifying transaction:', transactionId);
            // Create checksum
            const checksumString = `/pg/v1/status/${PHONEPE_CONFIG.merchantId}/${transactionId}${PHONEPE_CONFIG.saltKey}`;
            const sha256Hash = crypto
                .createHash('sha256')
                .update(checksumString)
                .digest('hex');
            const checksum = `${sha256Hash}###${PHONEPE_CONFIG.saltIndex}`;
            console.log('Checksum String:', checksumString);
            console.log('Checksum:', checksum);
            // Make API request
            const url = `${PHONEPE_CONFIG.apiEndpoint}/pg/v1/status/${PHONEPE_CONFIG.merchantId}/${transactionId}`;
            console.log('API URL:', url);
            const response = await axios.get(url, {
                headers: {
                    'Content-Type': 'application/json',
                    'X-VERIFY': checksum,
                    'X-MERCHANT-ID': PHONEPE_CONFIG.merchantId,
                    accept: 'application/json',
                },
            });
            console.log('PhonePe API Response Status:', response.status);
            console.log('PhonePe API Response Data:', JSON.stringify(response.data, null, 2));
            if (response.data.success && response.data.code === 'PAYMENT_SUCCESS') {
                return {
                    success: true,
                    status: 'COMPLETED',
                    amount: response.data.data.amount,
                    transactionId: response.data.data.transactionId,
                    merchantTransactionId: response.data.data.merchantTransactionId,
                    paymentInstrument: response.data.data.paymentInstrument,
                };
            }
            else if (response.data.code === 'PAYMENT_ERROR' ||
                response.data.code === 'PAYMENT_DECLINED') {
                return {
                    success: false,
                    status: 'FAILED',
                    error: response.data.message || 'Payment failed',
                };
            }
            else if (response.data.code === 'PAYMENT_PENDING') {
                return {
                    success: false,
                    status: 'PENDING',
                    error: 'Payment is pending',
                };
            }
            else {
                return {
                    success: false,
                    status: 'UNKNOWN',
                    error: response.data.message || 'Unknown payment status',
                };
            }
        }
        catch (error) {
            console.error('=== PhonePe API Error ===');
            console.error('Error:', error.message);
            if (error.response) {
                console.error('Response Status:', error.response.status);
                console.error('Response Data:', JSON.stringify(error.response.data, null, 2));
            }
            return {
                success: false,
                status: 'ERROR',
                error: ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || error.message,
            };
        }
    }
    // Standard CRUD operations below...
    async create(packagePurchase) {
        return this.packagePurchaseRepository.create(packagePurchase);
    }
    async count(where) {
        return this.packagePurchaseRepository.count(where);
    }
    async find(filter) {
        return this.packagePurchaseRepository.find(filter);
    }
    async updateAll(packagePurchase, where) {
        return this.packagePurchaseRepository.updateAll(packagePurchase, where);
    }
    async findById(id, filter) {
        return this.packagePurchaseRepository.findById(id, filter);
    }
    async updateById(id, packagePurchase) {
        await this.packagePurchaseRepository.updateById(id, packagePurchase);
    }
    async replaceById(id, packagePurchase) {
        await this.packagePurchaseRepository.replaceById(id, packagePurchase);
    }
    async deleteById(id) {
        await this.packagePurchaseRepository.deleteById(id);
    }
    async getPackagesByUser(userId) {
        return this.packagePurchaseRepository.find({
            where: {
                fkBuyerIdSellerId: userId,
                isActive: 1,
                deletedDate: null, // ignore deleted
            },
            order: ['packagePurchaseId DESC'],
            include: [{ relation: 'package' }], // include package details
        });
    }
};
exports.PackagePurchaseController = PackagePurchaseController;
tslib_1.__decorate([
    (0, rest_1.post)('/package-purchases/verify-payment'),
    (0, rest_1.response)(200, {
        description: 'Verify PhonePe payment and create package purchase',
        content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase) } },
    }),
    tslib_1.__param(0, (0, rest_1.requestBody)({
        content: {
            'application/json': {
                schema: {
                    type: 'object',
                    required: ['transactionId', 'packageId', 'userId', 'amount'],
                    properties: {
                        transactionId: { type: 'string' },
                        packageId: { type: 'number' },
                        userId: { type: 'number' },
                        amount: { type: 'number' },
                        packageDuration: { type: 'number' },
                        propertyVisit: { type: 'number' },
                        propertyAddToCart: { type: 'number' },
                        usertypeId: { type: 'number' },
                        isDemoMode: { type: 'boolean' },
                    },
                },
            },
        },
    })),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Object]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "verifyPayment", null);
tslib_1.__decorate([
    (0, rest_1.post)('/api/phonepe/callback'),
    (0, rest_1.response)(200, {
        description: 'PhonePe payment callback',
        content: { 'application/json': { schema: { type: 'object' } } },
    }),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", []),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "handleCallback", null);
tslib_1.__decorate([
    (0, rest_1.post)('/package-purchases'),
    (0, rest_1.response)(200, {
        description: 'PackagePurchase model instance',
        content: { 'application/json': { schema: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase) } },
    }),
    tslib_1.__param(0, (0, rest_1.requestBody)({
        content: {
            'application/json': {
                schema: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase, {
                    title: 'NewPackagePurchase',
                    exclude: ['packagePurchaseId'],
                }),
            },
        },
    })),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Object]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "create", null);
tslib_1.__decorate([
    (0, rest_1.get)('/package-purchases/count'),
    (0, rest_1.response)(200, {
        description: 'PackagePurchase model count',
        content: { 'application/json': { schema: repository_1.CountSchema } },
    }),
    tslib_1.__param(0, rest_1.param.where(models_1.PackagePurchase)),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Object]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "count", null);
tslib_1.__decorate([
    (0, rest_1.get)('/package-purchases'),
    (0, rest_1.response)(200, {
        description: 'Array of PackagePurchase model instances',
        content: {
            'application/json': {
                schema: {
                    type: 'array',
                    items: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase, { includeRelations: true }),
                },
            },
        },
    }),
    tslib_1.__param(0, rest_1.param.filter(models_1.PackagePurchase)),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Object]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "find", null);
tslib_1.__decorate([
    (0, rest_1.patch)('/package-purchases'),
    (0, rest_1.response)(200, {
        description: 'PackagePurchase PATCH success count',
        content: { 'application/json': { schema: repository_1.CountSchema } },
    }),
    tslib_1.__param(0, (0, rest_1.requestBody)({
        content: {
            'application/json': {
                schema: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase, { partial: true }),
            },
        },
    })),
    tslib_1.__param(1, rest_1.param.where(models_1.PackagePurchase)),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [models_1.PackagePurchase, Object]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "updateAll", null);
tslib_1.__decorate([
    (0, rest_1.get)('/package-purchases/{id}'),
    (0, rest_1.response)(200, {
        description: 'PackagePurchase model instance',
        content: {
            'application/json': {
                schema: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase, { includeRelations: true }),
            },
        },
    }),
    tslib_1.__param(0, rest_1.param.path.number('id')),
    tslib_1.__param(1, rest_1.param.filter(models_1.PackagePurchase, { exclude: 'where' })),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Number, Object]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "findById", null);
tslib_1.__decorate([
    (0, rest_1.patch)('/package-purchases/{id}'),
    (0, rest_1.response)(204, {
        description: 'PackagePurchase PATCH success',
    }),
    tslib_1.__param(0, rest_1.param.path.number('id')),
    tslib_1.__param(1, (0, rest_1.requestBody)({
        content: {
            'application/json': {
                schema: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase, { partial: true }),
            },
        },
    })),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Number, models_1.PackagePurchase]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "updateById", null);
tslib_1.__decorate([
    (0, rest_1.put)('/package-purchases/{id}'),
    (0, rest_1.response)(204, {
        description: 'PackagePurchase PUT success',
    }),
    tslib_1.__param(0, rest_1.param.path.number('id')),
    tslib_1.__param(1, (0, rest_1.requestBody)()),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Number, models_1.PackagePurchase]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "replaceById", null);
tslib_1.__decorate([
    (0, rest_1.del)('/package-purchases/{id}'),
    (0, rest_1.response)(204, {
        description: 'PackagePurchase DELETE success',
    }),
    tslib_1.__param(0, rest_1.param.path.number('id')),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Number]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "deleteById", null);
tslib_1.__decorate([
    (0, rest_1.get)('/package-purchases/user/{userId}'),
    (0, rest_1.response)(200, {
        description: 'Get package purchases for logged-in user',
        content: {
            'application/json': {
                schema: {
                    type: 'array',
                    items: (0, rest_1.getModelSchemaRef)(models_1.PackagePurchase, { includeRelations: true }),
                },
            },
        },
    }),
    tslib_1.__param(0, rest_1.param.path.number('userId')),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", [Number]),
    tslib_1.__metadata("design:returntype", Promise)
], PackagePurchaseController.prototype, "getPackagesByUser", null);
exports.PackagePurchaseController = PackagePurchaseController = tslib_1.__decorate([
    tslib_1.__param(0, (0, repository_1.repository)(repositories_1.PackagePurchaseRepository)),
    tslib_1.__param(1, (0, core_1.inject)(rest_2.RestBindings.Http.REQUEST)),
    tslib_1.__metadata("design:paramtypes", [repositories_1.PackagePurchaseRepository, Object])
], PackagePurchaseController);
//# sourceMappingURL=package-purchase.controller.js.map