// IRU Agreement API Routes
// Routes for agreement generation and e-signature

import { Router } from 'express';
import { agreementGenerator } from '@/core/iru/agreement/agreement-generator.service';
import { agreementValidator } from '@/core/iru/agreement/agreement-validator.service';
import { esignatureIntegration } from '@/core/iru/agreement/esignature-integration.service';
import { zeroTrustAuthMiddleware } from '@/integration/api-gateway/middleware/auth.middleware';
import { adminPermissionMiddleware } from '@/integration/api-gateway/middleware/admin-permission.middleware';
import prisma from '@/shared/database/prisma';

const router = Router();

// All agreement routes require authentication
router.use(zeroTrustAuthMiddleware);

/**
 * @route POST /api/v1/iru/agreement/generate
 * @desc Generate IRU agreement
 * @access Authenticated
 */
router.post('/generate', adminPermissionMiddleware, async (req, res, next) => {
  try {
    const { subscriptionId, templateId, variables } = req.body;
    const agreement = await agreementGenerator.generateAgreement({
      subscriptionId,
      templateId,
      variables,
    });

    // Validate agreement
    const validation = await agreementValidator.validate(
      agreement.agreementContent,
      agreement.variables
    );

    if (!validation.valid) {
      return res.status(400).json({
        success: false,
        error: {
          code: 'VALIDATION_ERROR',
          message: 'Agreement validation failed',
          details: validation.errors,
        },
        timestamp: new Date(),
      });
    }

    res.json({
      success: true,
      data: {
        ...agreement,
        validation: {
          valid: validation.valid,
          warnings: validation.warnings,
        },
      },
      timestamp: new Date(),
    });
  } catch (error) {
    return next(error);
  }
});

/**
 * @route GET /api/v1/iru/agreement/:agreementId
 * @desc Get agreement
 * @access Authenticated
 */
router.get('/:agreementId', async (req, res, next) => {
  try {
    const { agreementId } = req.params;
    const agreement = await prisma.iruAgreement.findUnique({
      where: { agreementId },
      include: {
        subscription: {
          include: {
            offering: true,
          },
        },
      },
    });

    if (!agreement) {
      return res.status(404).json({
        success: false,
        error: {
          code: 'NOT_FOUND',
          message: `Agreement ${agreementId} not found`,
        },
        timestamp: new Date(),
      });
    }

    res.json({
      success: true,
      data: {
        agreementId: agreement.agreementId,
        subscriptionId: agreement.subscription.subscriptionId,
        agreementType: agreement.agreementType,
        agreementVersion: agreement.agreementVersion,
        status: agreement.status,
        agreementContent: agreement.agreementContent,
        variables: agreement.variables,
        dbisSignedAt: agreement.dbisSignedAt,
        participantSignedAt: agreement.participantSignedAt,
        executedAt: agreement.executedAt,
        documentUrl: agreement.documentUrl,
      },
      timestamp: new Date(),
    });
  } catch (error) {
    return next(error);
  }
});

/**
 * @route POST /api/v1/iru/agreement/:agreementId/sign
 * @desc Initiate e-signature process
 * @access Authenticated
 */
router.post('/:agreementId/sign', async (req, res, next) => {
  try {
    const { agreementId } = req.params;
    const { signers } = req.body;

    const agreement = await prisma.iruAgreement.findUnique({
      where: { agreementId },
      include: {
        subscription: true,
      },
    });

    if (!agreement) {
      return res.status(404).json({
        success: false,
        error: {
          code: 'NOT_FOUND',
          message: `Agreement ${agreementId} not found`,
        },
        timestamp: new Date(),
      });
    }

    // Create e-signature envelope
    const esignature = await esignatureIntegration.createEnvelope({
      agreementId,
      signers,
    });

    // Update agreement with e-signature info
    await prisma.iruAgreement.update({
      where: { agreementId },
      data: {
        esignatureProvider: 'docusign',
        esignatureEnvelopeId: esignature.envelopeId,
        esignatureStatus: esignature.status,
        status: 'pending_signature',
      },
    });

    res.json({
      success: true,
      data: esignature,
      timestamp: new Date(),
    });
  } catch (error) {
    return next(error);
  }
});

/**
 * @route GET /api/v1/iru/agreement/:agreementId/signature-status
 * @desc Get e-signature status
 * @access Authenticated
 */
router.get('/:agreementId/signature-status', async (req, res, next) => {
  try {
    const { agreementId } = req.params;
    const agreement = await prisma.iruAgreement.findUnique({
      where: { agreementId },
    });

    if (!agreement || !agreement.esignatureEnvelopeId) {
      return res.status(404).json({
        success: false,
        error: {
          code: 'NOT_FOUND',
          message: `E-signature envelope not found for agreement ${agreementId}`,
        },
        timestamp: new Date(),
      });
    }

    const status = await esignatureIntegration.getEnvelopeStatus(agreement.esignatureEnvelopeId);

    // Update agreement status if completed
    if (status.status === 'completed' && agreement.status !== 'signed') {
      await prisma.iruAgreement.update({
        where: { agreementId },
        data: {
          status: 'signed',
          executedAt: new Date(),
        },
      });
    }

    res.json({
      success: true,
      data: status,
      timestamp: new Date(),
    });
  } catch (error) {
    return next(error);
  }
});

export default router;
