import type { Express } from "express";
import * as db from "./db";
import {
  getSalleWorkflowData,
  updateSalleWorkflowQuoteStatus,
} from "./salleReservationWorkflow";

/**
 * Register Express routes for email-based actions (validate/refuse requests)
 * These routes handle one-time token links sent in notification emails
 */
export function registerEmailActionRoutes(app: Express) {
  // Handle email action token - renders a confirmation page
  app.get("/api/email-action/:token", async (req, res) => {
    try {
      const { token } = req.params;
      const actionToken = await db.getEmailActionToken(token);

      if (!actionToken) {
        return res.status(404).send(renderPage("Lien invalide", "Ce lien d'action n'existe pas ou a été supprimé.", "error"));
      }

      if (actionToken.used) {
        return res.status(410).send(renderPage("Action déjà effectuée", "Ce lien a déjà été utilisé. La demande a été traitée.", "warning"));
      }

      if (new Date() > actionToken.expiresAt) {
        return res.status(410).send(renderPage("Lien expiré", "Ce lien d'action a expiré. Veuillez traiter la demande depuis l'interface d'administration.", "warning"));
      }

      // Get request details
      const request = await db.getRequestById(actionToken.requestId);
      if (!request) {
        return res.status(404).send(renderPage("Demande introuvable", "La demande associée à ce lien n'existe plus.", "error"));
      }

      const isQuoteAction = actionToken.action === "acceptation_devis_salle" || actionToken.action === "refus_devis_salle";

      if (isQuoteAction) {
        const workflow = getSalleWorkflowData(request.formData);
        if (workflow.quoteStatus !== "en_attente_association") {
          return res.status(410).send(
            renderPage(
              "Réponse déjà enregistrée",
              "L'association a déjà répondu à ce devis. Retournez au portail pour consulter l'état actuel du dossier.",
              "warning"
            )
          );
        }
      }

      // Check if request is still in a processable state
      if (request.status === 'validee' || request.status === 'refusee') {
        return res.status(410).send(renderPage("Demande déjà traitée", `Cette demande a déjà été ${request.status === 'validee' ? 'validée' : 'refusée'}.`, "warning"));
      }

      const actionLabel = actionToken.action === 'validee'
        ? 'Valider'
        : actionToken.action === 'acceptation_devis_salle'
          ? "Accepter le devis"
          : 'Refuser';
      const actionColor = actionToken.action === 'validee' || actionToken.action === "acceptation_devis_salle" ? '#18753C' : '#CE0500';
      const actionEmoji = actionToken.action === 'validee' || actionToken.action === "acceptation_devis_salle" ? '✅' : '❌';

      // Render confirmation page
      return res.send(renderConfirmationPage(request, actionToken, actionLabel, actionColor, actionEmoji, isQuoteAction));
    } catch (error) {
      console.error("[EmailAction] Error:", error);
      return res.status(500).send(renderPage("Erreur serveur", "Une erreur inattendue s'est produite. Veuillez réessayer.", "error"));
    }
  });

  // Handle confirmation POST
  app.post("/api/email-action/:token/confirm", async (req, res) => {
    try {
      const { token } = req.params;
      const actionToken = await db.getEmailActionToken(token);

      if (!actionToken) {
        return res.status(404).send(renderPage("Lien invalide", "Ce lien d'action n'existe pas.", "error"));
      }

      if (actionToken.used) {
        return res.status(410).send(renderPage("Action déjà effectuée", "Ce lien a déjà été utilisé.", "warning"));
      }

      if (new Date() > actionToken.expiresAt) {
        return res.status(410).send(renderPage("Lien expiré", "Ce lien a expiré.", "warning"));
      }

      const request = await db.getRequestById(actionToken.requestId);
      if (!request) {
        return res.status(404).send(renderPage("Demande introuvable", "La demande n'existe plus.", "error"));
      }

      if (actionToken.action === "acceptation_devis_salle" || actionToken.action === "refus_devis_salle") {
        const workflow = getSalleWorkflowData(request.formData);
        if (workflow.quoteStatus !== "en_attente_association") {
          return res.status(410).send(
            renderPage(
              "Réponse déjà enregistrée",
              "L'association a déjà répondu à ce devis. Aucun nouvel enregistrement n'est nécessaire.",
              "warning"
            )
          );
        }
      }

      if (request.status === 'validee' || request.status === 'refusee') {
        return res.status(410).send(renderPage("Demande déjà traitée", `Cette demande a déjà été ${request.status === 'validee' ? 'validée' : 'refusée'}.`, "warning"));
      }

      let successTitle = "";
      let successMessage = "";

      if (actionToken.action === "acceptation_devis_salle" || actionToken.action === "refus_devis_salle") {
        const nextWorkflowFormData = updateSalleWorkflowQuoteStatus(
          request.formData,
          actionToken.action === "acceptation_devis_salle" ? "accepte" : "refuse"
        );
        const workflow = getSalleWorkflowData(nextWorkflowFormData);
        const isAccepted = actionToken.action === "acceptation_devis_salle";
        const nextStatus = isAccepted ? request.status : "refusee";

        await db.updateRequest(actionToken.requestId, {
          formData: nextWorkflowFormData,
          status: nextStatus,
          dateTraitement: isAccepted ? request.dateTraitement : new Date(),
          commentaireAdmin: isAccepted
            ? request.commentaireAdmin
            : ((request.commentaireAdmin ? `${request.commentaireAdmin}\n\n` : "") + "Devis refusé par l'association via email"),
        });

        await db.createRequestHistory({
          requestId: actionToken.requestId,
          action: isAccepted ? "modification" : "refus",
          ancienStatut: request.status,
          nouveauStatut: nextStatus,
          userId: 0,
          commentaire: isAccepted
            ? "Devis accepté par l'association via email"
            : "Devis refusé par l'association via email",
        });

        await db.createAdminNotification({
          type: "systeme",
          titre: isAccepted ? `Devis accepté : ${request.titre}` : `Devis refusé : ${request.titre}`,
          message: isAccepted
            ? `L'association a accepté le devis pour la demande "${request.titre}".`
            : `L'association a refusé le devis pour la demande "${request.titre}".`,
          lien: `/dashboard/requests/${request.id}`,
        });

        successTitle = isAccepted ? "✅ Devis accepté" : "❌ Devis refusé";
        successMessage = isAccepted
          ? `Votre accord a bien été enregistré pour "${request.titre}". Le dossier repart vers l'hôtesse pour transmission à la Directrice.`
          : `Votre refus a bien été enregistré pour "${request.titre}".`;
      } else {
        // Process the admin validation/refusal action
        const newStatus = actionToken.action;
        const commentaire = req.body?.commentaire || (newStatus === 'validee' ? 'Demande validée via email' : 'Demande refusée via email');

        await db.updateRequest(actionToken.requestId, {
          status: newStatus,
          commentaireAdmin: commentaire,
          dateTraitement: new Date(),
        });

        await db.createRequestHistory({
          requestId: actionToken.requestId,
          action: newStatus === 'validee' ? 'validation' : 'refus',
          ancienStatut: request.status,
          nouveauStatut: newStatus,
          userId: actionToken.usedBy || 0,
          commentaire: commentaire,
        });

        successTitle = newStatus === 'validee' ? '✅ Demande validée' : '❌ Demande refusée';
        successMessage = newStatus === 'validee' 
          ? `La demande "${request.titre}" a été validée avec succès.`
          : `La demande "${request.titre}" a été refusée.`;
      }

      // Mark token as used
      await db.markTokenAsUsed(token, 0);

      return res.send(renderPage(successTitle, successMessage, "success"));
    } catch (error) {
      console.error("[EmailAction] Confirm error:", error);
      return res.status(500).send(renderPage("Erreur serveur", "Une erreur s'est produite lors du traitement.", "error"));
    }
  });
}

function renderConfirmationPage(
  request: any, 
  actionToken: any, 
  actionLabel: string, 
  actionColor: string,
  actionEmoji: string,
  isQuoteAction: boolean
): string {
  const statusLabels: Record<string, string> = {
    brouillon: 'Brouillon',
    soumise: 'Soumise',
    en_cours_traitement: 'En cours',
    information_complementaire: 'Info. complémentaire',
    validee: 'Validée',
    refusee: 'Refusée',
  };

  const typeLabels: Record<string, string> = {
    subvention_fonctionnement: 'Subvention de fonctionnement',
    subvention_projet: 'Subvention de projet',
    agrement_jeunesse_education: 'Agrément Jeunesse et Éducation',
    agrement_sport: 'Agrément Sport',
    autorisation_occupation: 'Autorisation d\'occupation',
    demande_salle: 'Demande de salle',
    demande_materiel_evenementiel: 'Demande du matériel événementiel',
    autre: 'Autre',
  };

  const montant = request.montantDemande ? `${(request.montantDemande / 100).toLocaleString('fr-FR')} €` : 'Non spécifié';

  return `<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${actionEmoji} ${actionLabel} la demande - Portail Associations</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: 'Marianne', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f6f6f6; color: #161616; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; }
    .container { max-width: 600px; width: 100%; background: white; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); overflow: hidden; }
    .header { background: #000091; color: white; padding: 24px 32px; }
    .header h1 { font-size: 20px; font-weight: 700; margin-bottom: 4px; }
    .header p { font-size: 14px; opacity: 0.8; }
    .content { padding: 32px; }
    .badge { display: inline-block; padding: 4px 12px; border-radius: 4px; font-size: 12px; font-weight: 600; margin-bottom: 16px; }
    .badge-action { background: ${actionColor}15; color: ${actionColor}; border: 1px solid ${actionColor}30; }
    .info-grid { display: grid; gap: 12px; margin-bottom: 24px; }
    .info-row { display: flex; border-bottom: 1px solid #eee; padding-bottom: 8px; }
    .info-label { font-weight: 600; color: #666; min-width: 140px; font-size: 14px; }
    .info-value { font-size: 14px; color: #161616; }
    .warning-box { background: #FEF7DA; border-left: 4px solid #D64D00; padding: 16px; border-radius: 0 4px 4px 0; margin-bottom: 24px; }
    .warning-box p { font-size: 14px; color: #3A3A3A; }
    .comment-box { margin-bottom: 24px; }
    .comment-box label { display: block; font-weight: 600; font-size: 14px; margin-bottom: 8px; }
    .comment-box textarea { width: 100%; min-height: 100px; padding: 12px; border: 1px solid #ddd; border-radius: 4px; font-family: inherit; font-size: 14px; resize: vertical; }
    .comment-box textarea:focus { outline: none; border-color: #000091; box-shadow: 0 0 0 2px #000091 20; }
    .actions { display: flex; gap: 12px; justify-content: flex-end; }
    .btn { padding: 12px 24px; border-radius: 4px; font-size: 14px; font-weight: 600; cursor: pointer; border: none; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; transition: opacity 0.2s; }
    .btn:hover { opacity: 0.85; }
    .btn-primary { background: ${actionColor}; color: white; }
    .btn-secondary { background: white; color: #161616; border: 1px solid #ddd; }
    .footer { padding: 16px 32px; background: #f6f6f6; border-top: 1px solid #eee; text-align: center; font-size: 12px; color: #666; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>Portail Associations</h1>
      <p>Traitement de demande par email</p>
    </div>
    <div class="content">
      <span class="badge badge-action">${actionEmoji} ${actionLabel}</span>
      
      <div class="info-grid">
        <div class="info-row">
          <span class="info-label">Demande</span>
          <span class="info-value">${escapeHtml(request.titre)}</span>
        </div>
        <div class="info-row">
          <span class="info-label">Type</span>
          <span class="info-value">${typeLabels[request.type] || request.type}</span>
        </div>
        <div class="info-row">
          <span class="info-label">Statut actuel</span>
          <span class="info-value">${statusLabels[request.status] || request.status}</span>
        </div>
        <div class="info-row">
          <span class="info-label">Montant demandé</span>
          <span class="info-value">${montant}</span>
        </div>
        ${request.description ? `<div class="info-row">
          <span class="info-label">Description</span>
          <span class="info-value">${escapeHtml(request.description).substring(0, 200)}${request.description.length > 200 ? '...' : ''}</span>
        </div>` : ''}
      </div>

      <div class="warning-box">
        <p><strong>Attention :</strong> Vous êtes sur le point de <strong>${actionLabel.toLowerCase()}</strong> ${isQuoteAction ? 'ce devis / cette mise à disposition' : 'cette demande'}. Cette action est irréversible depuis cet email.</p>
      </div>

      <form method="POST" action="/api/email-action/${actionToken.token}/confirm">
        <div class="comment-box">
          <label for="commentaire">Commentaire (optionnel) :</label>
          <textarea id="commentaire" name="commentaire" placeholder="${isQuoteAction ? "Ajoutez un commentaire à destination de l'administration..." : "Ajoutez un commentaire pour l'association..."}"></textarea>
        </div>

        <div class="actions">
          <a href="javascript:window.close()" class="btn btn-secondary">Annuler</a>
          <button type="submit" class="btn btn-primary">${actionEmoji} Confirmer : ${actionLabel}</button>
        </div>
      </form>
    </div>
    <div class="footer">
      <p>Ce lien expire le ${actionToken.expiresAt.toLocaleDateString('fr-FR', { day: 'numeric', month: 'long', year: 'numeric' })} — Portail Associations</p>
    </div>
  </div>
</body>
</html>`;
}

function renderPage(title: string, message: string, type: "success" | "error" | "warning"): string {
  const colors = {
    success: { bg: '#B8FEC9', border: '#18753C', icon: '✅' },
    error: { bg: '#FFE9E6', border: '#CE0500', icon: '❌' },
    warning: { bg: '#FEF7DA', border: '#D64D00', icon: '⚠️' },
  };
  const c = colors[type];

  return `<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${title} - Portail Associations</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: 'Marianne', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f6f6f6; color: #161616; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; }
    .container { max-width: 500px; width: 100%; background: white; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.08); overflow: hidden; }
    .header { background: #000091; color: white; padding: 24px 32px; }
    .header h1 { font-size: 20px; font-weight: 700; }
    .content { padding: 32px; text-align: center; }
    .icon { font-size: 48px; margin-bottom: 16px; }
    .alert { background: ${c.bg}; border-left: 4px solid ${c.border}; padding: 16px; border-radius: 0 4px 4px 0; margin-bottom: 24px; text-align: left; }
    .alert h2 { font-size: 16px; margin-bottom: 8px; color: ${c.border}; }
    .alert p { font-size: 14px; color: #3A3A3A; }
    .btn { display: inline-block; padding: 12px 24px; background: #000091; color: white; border-radius: 4px; text-decoration: none; font-weight: 600; font-size: 14px; margin-top: 16px; }
    .btn:hover { opacity: 0.85; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>Portail Associations</h1>
    </div>
    <div class="content">
      <div class="icon">${c.icon}</div>
      <div class="alert">
        <h2>${escapeHtml(title)}</h2>
        <p>${escapeHtml(message)}</p>
      </div>
      <a href="/" class="btn">Retour au portail</a>
    </div>
  </div>
</body>
</html>`;
}

function escapeHtml(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}
