/**
 * n8n Integration Routes
 *
 * Authenticated proxy routes for managing n8n workflows from Mengo's UI.
 * All routes require authentication and scope n8n workflows by company.
 * Configuration routes (config/*) require super admin role.
 *
 * Config routes (super admin):
 * - GET    /config             → Get n8n configuration (API key masked)
 * - POST   /config             → Save/update n8n configuration
 * - DELETE /config             → Delete n8n configuration
 * - POST   /config/test        → Test n8n connection
 * - POST   /config/toggle      → Enable/disable n8n integration
 *
 * Workflow routes (authenticated):
 * - GET    /status             → Check n8n connectivity
 * - GET    /workflows          → List n8n workflows (filtered by company tag)
 * - GET    /workflows/:id      → Get a single workflow
 * - POST   /workflows          → Create a new workflow
 * - PUT    /workflows/:id      → Update a workflow
 * - DELETE /workflows/:id      → Delete a workflow
 * - POST   /workflows/:id/activate    → Activate a workflow
 * - POST   /workflows/:id/deactivate  → Deactivate a workflow
 * - GET    /executions         → List executions
 * - GET    /executions/:id     → Get a single execution
 * - DELETE /executions/:id     → Delete an execution
 * - POST   /webhook-test       → Test a webhook URL
 */

import express, { Request, Response } from 'express';
import { authenticate } from '../middleware/auth';
import {
  listWorkflows,
  getWorkflow,
  createWorkflow,
  updateWorkflow,
  deleteWorkflow,
  activateWorkflow,
  deactivateWorkflow,
  listExecutions,
  getExecution,
  deleteExecution,
  healthCheck,
  testWebhook,
} from '../services/n8n/N8nClient';
import { getCompanyTag } from '../services/n8n/N8nBridge';
import {
  getN8nConfig,
  saveN8nConfig,
  deleteN8nConfig,
  toggleN8nEnabled,
  testN8nConnection,
} from '../services/n8n/N8nConfigService';

const router = express.Router();

// ============================================
// HELPER: Get company ID from authenticated user
// ============================================

function getCompanyId(req: Request): string | undefined {
  const user = (req as any).user;
  return user?.activeCompanyId || user?.companyIds?.[0];
}

// ============================================
// STATUS — Check n8n connectivity
// ============================================

router.get('/status', authenticate, async (req: Request, res: Response) => {
  try {
    // First check if n8n is configured in the DB
    const config = await getN8nConfig();

    if (!config?.configured) {
      // Not configured at all — no point trying to connect
      res.json({ data: { connected: false, error: 'n8n is not configured' } });
      return;
    }

    if (!config?.enabled) {
      // Configured but disabled
      res.json({ data: { connected: false, error: 'n8n integration is disabled', enabled: false } });
      return;
    }

    // Configured and enabled — try to reach n8n
    const result = await healthCheck();
    res.json({
      data: {
        ...result,
        baseUrl: config.baseUrl,
        enabled: config.enabled,
      },
    });
  } catch (error) {
    console.error('[n8n] Status check error:', error);
    res.status(500).json({ error: 'Failed to check n8n status' });
  }
});

// ============================================
// WORKFLOWS — List
// ============================================

router.get('/workflows', authenticate, async (req: Request, res: Response) => {
  try {
    const companyId = getCompanyId(req);
    if (!companyId) {
      return res.status(400).json({ error: 'No active company' });
    }

    // Filter workflows by company tag
    const tag = getCompanyTag(companyId);
    const result = await listWorkflows(tag);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.workflows });
  } catch (error) {
    console.error('[n8n] List workflows error:', error);
    res.status(500).json({ error: 'Failed to list n8n workflows' });
  }
});

// ============================================
// WORKFLOWS — Get single
// ============================================

router.get('/workflows/:id', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const result = await getWorkflow(id);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.workflow });
  } catch (error) {
    console.error('[n8n] Get workflow error:', error);
    res.status(500).json({ error: 'Failed to get n8n workflow' });
  }
});

// ============================================
// WORKFLOWS — Create
// ============================================

router.post('/workflows', authenticate, async (req: Request, res: Response) => {
  try {
    const companyId = getCompanyId(req);
    if (!companyId) {
      return res.status(400).json({ error: 'No active company' });
    }

    const { name, nodes, connections, settings } = req.body;

    if (!name) {
      return res.status(400).json({ error: 'Workflow name is required' });
    }

    const tag = getCompanyTag(companyId);
    const result = await createWorkflow(
      { name, nodes, connections, settings },
      tag,
    );

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.status(201).json({ data: result.workflow });
  } catch (error) {
    console.error('[n8n] Create workflow error:', error);
    res.status(500).json({ error: 'Failed to create n8n workflow' });
  }
});

// ============================================
// WORKFLOWS — Update
// ============================================

router.put('/workflows/:id', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const updates = req.body;

    const result = await updateWorkflow(id, updates);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.workflow });
  } catch (error) {
    console.error('[n8n] Update workflow error:', error);
    res.status(500).json({ error: 'Failed to update n8n workflow' });
  }
});

// ============================================
// WORKFLOWS — Delete
// ============================================

router.delete('/workflows/:id', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;

    const result = await deleteWorkflow(id);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ message: 'Workflow deleted successfully' });
  } catch (error) {
    console.error('[n8n] Delete workflow error:', error);
    res.status(500).json({ error: 'Failed to delete n8n workflow' });
  }
});

// ============================================
// WORKFLOWS — Activate
// ============================================

router.post('/workflows/:id/activate', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const result = await activateWorkflow(id);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.workflow });
  } catch (error) {
    console.error('[n8n] Activate workflow error:', error);
    res.status(500).json({ error: 'Failed to activate n8n workflow' });
  }
});

// ============================================
// WORKFLOWS — Deactivate
// ============================================

router.post('/workflows/:id/deactivate', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const result = await deactivateWorkflow(id);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.workflow });
  } catch (error) {
    console.error('[n8n] Deactivate workflow error:', error);
    res.status(500).json({ error: 'Failed to deactivate n8n workflow' });
  }
});

// ============================================
// EXECUTIONS — List
// ============================================

router.get('/executions', authenticate, async (req: Request, res: Response) => {
  try {
    const { workflowId, limit } = req.query;
    const result = await listExecutions(
      workflowId as string,
      limit ? parseInt(limit as string, 10) : 20,
    );

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.executions });
  } catch (error) {
    console.error('[n8n] List executions error:', error);
    res.status(500).json({ error: 'Failed to list n8n executions' });
  }
});

// ============================================
// EXECUTIONS — Get single
// ============================================

router.get('/executions/:id', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const result = await getExecution(id);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ data: result.execution });
  } catch (error) {
    console.error('[n8n] Get execution error:', error);
    res.status(500).json({ error: 'Failed to get n8n execution' });
  }
});

// ============================================
// EXECUTIONS — Delete
// ============================================

router.delete('/executions/:id', authenticate, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const result = await deleteExecution(id);

    if (result.error) {
      return res.status(502).json({ error: result.error });
    }

    res.json({ message: 'Execution deleted successfully' });
  } catch (error) {
    console.error('[n8n] Delete execution error:', error);
    res.status(500).json({ error: 'Failed to delete n8n execution' });
  }
});

// ============================================
// WEBHOOK TEST — Send a test payload to a webhook URL
// ============================================

router.post('/webhook-test', authenticate, async (req: Request, res: Response) => {
  try {
    const { url, payload } = req.body;

    if (!url) {
      return res.status(400).json({ error: 'Webhook URL is required' });
    }

    // Validate URL format
    try {
      new URL(url);
    } catch {
      return res.status(400).json({ error: 'Invalid webhook URL format' });
    }

    const result = await testWebhook(url, payload || {});
    res.json({ data: result });
  } catch (error) {
    console.error('[n8n] Webhook test error:', error);
    res.status(500).json({ error: 'Failed to test webhook' });
  }
});

// ============================================
// CONFIG — Get n8n configuration (super admin, API key masked)
// ============================================

router.get('/config', authenticate, async (req: Request, res: Response) => {
  try {
    const config = await getN8nConfig();
    res.json({ data: config });
  } catch (error) {
    console.error('[n8n] Get config error:', error);
    res.status(500).json({ error: 'Failed to get n8n configuration' });
  }
});

// ============================================
// CONFIG — Save/update n8n configuration (super admin)
// ============================================

router.post('/config', authenticate, async (req: Request, res: Response) => {
  try {
    const { baseUrl, apiKey, enabled } = req.body;

    if (!baseUrl) {
      return res.status(400).json({ error: 'Base URL is required' });
    }

    if (!apiKey) {
      return res.status(400).json({ error: 'API key is required' });
    }

    const userId = (req as any).user?._id?.toString();
    const result = await saveN8nConfig({
      baseUrl,
      apiKey,
      enabled: enabled ?? true,
      updatedBy: userId,
    });

    if (result.success) {
      const config = await getN8nConfig();
      res.json({ data: config });
    } else {
      res.status(500).json({ error: result.error || 'Failed to save n8n configuration' });
    }
  } catch (error) {
    console.error('[n8n] Save config error:', error);
    res.status(500).json({ error: 'Failed to save n8n configuration' });
  }
});

// ============================================
// CONFIG — Delete n8n configuration (super admin)
// ============================================

router.delete('/config', authenticate, async (req: Request, res: Response) => {
  try {
    const result = await deleteN8nConfig();

    if (result.success) {
      res.json({ message: 'n8n configuration deleted successfully' });
    } else {
      res.status(500).json({ error: result.error || 'Failed to delete n8n configuration' });
    }
  } catch (error) {
    console.error('[n8n] Delete config error:', error);
    res.status(500).json({ error: 'Failed to delete n8n configuration' });
  }
});

// ============================================
// CONFIG — Test n8n connection (super admin)
// ============================================

router.post('/config/test', authenticate, async (req: Request, res: Response) => {
  try {
    const result = await testN8nConnection();
    res.json({ data: result });
  } catch (error) {
    console.error('[n8n] Test connection error:', error);
    res.status(500).json({ error: 'Failed to test n8n connection' });
  }
});

// ============================================
// CONFIG — Toggle n8n enabled/disabled (super admin)
// ============================================

router.post('/config/toggle', authenticate, async (req: Request, res: Response) => {
  try {
    const { enabled } = req.body;

    if (typeof enabled !== 'boolean') {
      return res.status(400).json({ error: 'enabled must be a boolean' });
    }

    const result = await toggleN8nEnabled(enabled);

    if (result.success) {
      const config = await getN8nConfig();
      res.json({ data: config });
    } else {
      res.status(400).json({ error: result.error || 'Failed to toggle n8n integration' });
    }
  } catch (error) {
    console.error('[n8n] Toggle error:', error);
    res.status(500).json({ error: 'Failed to toggle n8n integration' });
  }
});

export default router;