"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.trackShipment = exports.cancelShipment = exports.schedulePickup = exports.generateAwb = exports.createShipment = exports.testShippingConnection = exports.toggleShippingProvider = exports.deleteShippingProvider = exports.updateShippingProvider = exports.createShippingProvider = exports.getAdminShippingProviders = void 0;
const database_1 = __importDefault(require("../../../config/database"));
const response_utils_1 = require("../../../utils/response.utils");
const encryption_utils_1 = require("../../../utils/encryption.utils");
const shipping_provider_factory_1 = require("../services/shipping-provider.factory");
const shipping_service_1 = require("../services/shipping.service");
const logger_1 = require("../../../config/logger");
// 1. Get Admin Shipping Providers settings list
const getAdminShippingProviders = async (req, res) => {
    try {
        if (res.locals.userRole !== 'ADMIN' && req.user?.role !== 'ADMIN') {
            return (0, response_utils_1.sendError)(res, 'Forbidden', null, 403);
        }
        const providers = await database_1.default.shippingProvider.findMany({
            orderBy: { priority: 'asc' },
        });
        const maskedProviders = providers.map((p) => ({
            ...p,
            apiPassword: p.apiPassword ? (0, encryption_utils_1.maskSecret)(p.apiPassword) : null,
            apiToken: p.apiToken ? (0, encryption_utils_1.maskSecret)(p.apiToken) : null,
            clientSecret: p.clientSecret ? (0, encryption_utils_1.maskSecret)(p.clientSecret) : null,
            secretKey: p.secretKey ? (0, encryption_utils_1.maskSecret)(p.secretKey) : null,
        }));
        return (0, response_utils_1.sendSuccess)(res, 'Admin shipping configurations loaded', { providers: maskedProviders });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to fetch shipping configurations', error.message, 500);
    }
};
exports.getAdminShippingProviders = getAdminShippingProviders;
// 2. Create Shipping Provider setting
const createShippingProvider = async (req, res) => {
    try {
        const body = req.body;
        const provider = await database_1.default.shippingProvider.create({
            data: {
                providerName: body.providerName.toUpperCase(),
                displayName: body.displayName,
                isEnabled: body.isEnabled ?? true,
                environment: body.environment || 'sandbox',
                apiEmail: body.apiEmail,
                apiPassword: body.apiPassword ? (0, encryption_utils_1.encrypt)(body.apiPassword) : null,
                apiToken: body.apiToken ? (0, encryption_utils_1.encrypt)(body.apiToken) : null,
                clientId: body.clientId,
                clientSecret: body.clientSecret ? (0, encryption_utils_1.encrypt)(body.clientSecret) : null,
                apiKey: body.apiKey,
                secretKey: body.secretKey ? (0, encryption_utils_1.encrypt)(body.secretKey) : null,
                pickupLocation: body.pickupLocation,
                warehouseName: body.warehouseName,
                warehouseAddress: body.warehouseAddress,
                contactPerson: body.contactPerson,
                phone: body.phone,
                gstNumber: body.gstNumber,
                pincode: body.pincode,
                callbackUrl: body.callbackUrl,
                webhookUrl: body.webhookUrl,
                trackingUrl: body.trackingUrl,
                priority: body.priority ?? 0,
                defaultProvider: body.defaultProvider ?? false,
            },
        });
        return (0, response_utils_1.sendSuccess)(res, 'Shipping provider added successfully', { id: provider.id });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to add shipping provider', error.message, 500);
    }
};
exports.createShippingProvider = createShippingProvider;
// 3. Update Shipping Provider settings
const updateShippingProvider = async (req, res) => {
    try {
        const { id } = req.params;
        const body = req.body;
        const existing = await database_1.default.shippingProvider.findUnique({ where: { id } });
        if (!existing)
            return (0, response_utils_1.sendError)(res, 'Provider configuration not found', null, 404);
        const apiPassword = body.apiPassword === '************' ? existing.apiPassword : (body.apiPassword ? (0, encryption_utils_1.encrypt)(body.apiPassword) : null);
        const apiToken = body.apiToken === '************' ? existing.apiToken : (body.apiToken ? (0, encryption_utils_1.encrypt)(body.apiToken) : null);
        const clientSecret = body.clientSecret === '************' ? existing.clientSecret : (body.clientSecret ? (0, encryption_utils_1.encrypt)(body.clientSecret) : null);
        const secretKey = body.secretKey === '************' ? existing.secretKey : (body.secretKey ? (0, encryption_utils_1.encrypt)(body.secretKey) : null);
        await database_1.default.shippingProvider.update({
            where: { id },
            data: {
                displayName: body.displayName,
                isEnabled: body.isEnabled,
                environment: body.environment,
                apiEmail: body.apiEmail,
                apiPassword,
                apiToken,
                clientId: body.clientId,
                clientSecret,
                apiKey: body.apiKey,
                secretKey,
                pickupLocation: body.pickupLocation,
                warehouseName: body.warehouseName,
                warehouseAddress: body.warehouseAddress,
                contactPerson: body.contactPerson,
                phone: body.phone,
                gstNumber: body.gstNumber,
                pincode: body.pincode,
                callbackUrl: body.callbackUrl,
                webhookUrl: body.webhookUrl,
                trackingUrl: body.trackingUrl,
                priority: body.priority,
                defaultProvider: body.defaultProvider,
            },
        });
        // Write audit log entry
        await database_1.default.shippingAudit.create({
            data: {
                providerId: id,
                action: 'PROVIDER_CONFIG_UPDATED',
                performedBy: req.user?.adminId || 'ADMIN',
                details: `Updated settings parameters for shipping provider: ${existing.providerName}`,
            },
        });
        return (0, response_utils_1.sendSuccess)(res, 'Shipping provider updated successfully');
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Update failed', error.message, 500);
    }
};
exports.updateShippingProvider = updateShippingProvider;
// 4. Delete config
const deleteShippingProvider = async (req, res) => {
    try {
        const { id } = req.params;
        await database_1.default.shippingProvider.delete({ where: { id } });
        return (0, response_utils_1.sendSuccess)(res, 'Shipping provider settings deleted successfully');
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Deletion failed', error.message, 500);
    }
};
exports.deleteShippingProvider = deleteShippingProvider;
// 5. Toggle enable / disable status
const toggleShippingProvider = async (req, res) => {
    try {
        const { id } = req.params;
        const existing = await database_1.default.shippingProvider.findUnique({ where: { id } });
        if (!existing)
            return (0, response_utils_1.sendError)(res, 'Shipping provider not found', null, 404);
        const updated = await database_1.default.shippingProvider.update({
            where: { id },
            data: { isEnabled: !existing.isEnabled },
        });
        return (0, response_utils_1.sendSuccess)(res, `Provider status toggled to: ${updated.isEnabled ? 'Enabled' : 'Disabled'}`, { isEnabled: updated.isEnabled });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Toggle failed', error.message, 500);
    }
};
exports.toggleShippingProvider = toggleShippingProvider;
// 6. Test connection connectivity check
const testShippingConnection = async (req, res) => {
    try {
        const { id } = req.params;
        const provider = await database_1.default.shippingProvider.findUnique({ where: { id } });
        if (!provider)
            return (0, response_utils_1.sendError)(res, 'Shipping provider config not found', null, 404);
        const providerClient = await shipping_provider_factory_1.ShippingProviderFactory.getProvider(provider.providerName);
        const testResult = await providerClient.testConnection();
        logger_1.logger.info(`Tested shipping connection for ${provider.providerName}: ${testResult.connected ? 'CONNECTED' : 'FAILED'}`);
        return (0, response_utils_1.sendSuccess)(res, 'Tested connection parameters', {
            connected: testResult.connected,
            status: testResult.connected ? 'Connected' : 'Failed',
            message: testResult.message,
        });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Connection validation check failed', error.message, 500);
    }
};
exports.testShippingConnection = testShippingConnection;
// 7. Create shipment dispatch
const createShipment = async (req, res) => {
    try {
        const { orderId } = req.body;
        const shippingOrder = await shipping_service_1.ShippingService.syncOrderToShipping(orderId);
        return (0, response_utils_1.sendSuccess)(res, 'Shipping order synced successfully', { shippingOrder });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Failed to sync shipping order', error.message, 500);
    }
};
exports.createShipment = createShipment;
// 8. Generate AWB
const generateAwb = async (req, res) => {
    try {
        const { shippingOrderId } = req.body;
        const updated = await shipping_service_1.ShippingService.generateAwb(shippingOrderId);
        return (0, response_utils_1.sendSuccess)(res, 'AWB tracking number assigned successfully', { shippingOrder: updated });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'AWB generation failed', error.message, 500);
    }
};
exports.generateAwb = generateAwb;
// 9. Schedule Pickup
const schedulePickup = async (req, res) => {
    try {
        const { shippingOrderId, pickupTime } = req.body;
        const pickup = await shipping_service_1.ShippingService.schedulePickup(shippingOrderId, new Date(pickupTime));
        return (0, response_utils_1.sendSuccess)(res, 'Pickup scheduled successfully', { pickup });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Pickup scheduling failed', error.message, 500);
    }
};
exports.schedulePickup = schedulePickup;
// 10. Cancel Shipment
const cancelShipment = async (req, res) => {
    try {
        const { shippingOrderId } = req.body;
        const result = await shipping_service_1.ShippingService.cancelShipment(shippingOrderId);
        return (0, response_utils_1.sendSuccess)(res, 'Shipment order cancelled successfully', result);
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Cancellation failed', error.message, 500);
    }
};
exports.cancelShipment = cancelShipment;
// 11. Track AWB realtime
const trackShipment = async (req, res) => {
    try {
        const { trackingNumber } = req.params;
        const tracking = await shipping_service_1.ShippingService.trackShipment(trackingNumber);
        return (0, response_utils_1.sendSuccess)(res, 'Shipment tracking timeline retrieved', { tracking });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Real-time tracking fetch failed', error.message, 500);
    }
};
exports.trackShipment = trackShipment;
//# sourceMappingURL=shipping-config.controller.js.map