const { query } = require("../../../database/dbpromise");
const crypto = require("crypto");
const randomstring = require("randomstring");

/**
 * Generate unique webhook ID
 */
function generateWebhookId() {
  return randomstring.generate(6);
}

/**
 * Generate secret key for webhook verification
 */
function generateSecret() {
  return crypto.randomBytes(32).toString("hex");
}

/**
 * Check if webhook addon is enabled
 */
function checkWebhook() {
  return true;
}

/**
 * Get all webhooks for a user
 */
async function getWebhooks(uid) {
  try {
    const webhooks = await query(
      `SELECT * FROM webhooks WHERE uid = ? ORDER BY created_at DESC`,
      [uid]
    );

    return {
      success: true,
      data: webhooks,
    };
  } catch (error) {
    console.error("Error fetching webhooks:", error);
    return {
      success: false,
      message: error.message,
    };
  }
}

/**
 * Add new webhook
 */
async function addWebhook(uid, name, description, method = "POST", secret = null) {
  try {
    const webhookId = generateWebhookId();
    const webhookSecret = secret || generateSecret();

    await query(
      `INSERT INTO webhooks (uid, name, description, method, secret, webhook_id, is_active) 
       VALUES (?, ?, ?, ?, ?, ?, ?)`,
      [uid, name, description || "", method, webhookSecret, webhookId, 1]
    );

    return {
      success: true,
      message: "Webhook created successfully",
      data: {
        webhook_id: webhookId,
        webhook_url: `${process.env.BACKURI}/api/webhook/webhook/${webhookId}`,
        secret: webhookSecret,
      },
    };
  } catch (error) {
    console.error("Error creating webhook:", error);
    return {
      success: false,
      message: error.message,
    };
  }
}

/**
 * Update existing webhook
 */
async function updateWebhook(uid, webhookId, name, description, method, secret, isActive) {
  try {
    const [webhook] = await query(
      `SELECT * FROM webhooks WHERE webhook_id = ? AND uid = ?`,
      [webhookId, uid]
    );

    if (!webhook) {
      return {
        success: false,
        message: "Webhook not found",
      };
    }

    const updateSecret = secret !== undefined ? secret : webhook.secret;

    await query(
      `UPDATE webhooks 
       SET name = ?, description = ?, method = ?, secret = ?, is_active = ? 
       WHERE webhook_id = ? AND uid = ?`,
      [name, description || "", method, updateSecret, isActive ? 1 : 0, webhookId, uid]
    );

    return {
      success: true,
      message: "Webhook updated successfully",
    };
  } catch (error) {
    console.error("Error updating webhook:", error);
    return {
      success: false,
      message: error.message,
    };
  }
}

/**
 * Delete webhook
 */
async function deleteWebhook(uid, webhookId) {
  try {
    const [webhook] = await query(
      `SELECT * FROM webhooks WHERE webhook_id = ? AND uid = ?`,
      [webhookId, uid]
    );

    if (!webhook) {
      return {
        success: false,
        message: "Webhook not found",
      };
    }

    await query(
      `DELETE FROM webhooks WHERE webhook_id = ? AND uid = ?`,
      [webhookId, uid]
    );

    return {
      success: true,
      message: "Webhook deleted successfully",
    };
  } catch (error) {
    console.error("Error deleting webhook:", error);
    return {
      success: false,
      message: error.message,
    };
  }
}

/**
 * Handle incoming webhook request
 */
async function handleWebhook(webhookId, method, body, headers) {
  try {
    const [webhook] = await query(
      `SELECT * FROM webhooks WHERE webhook_id = ? AND is_active = ?`,
      [webhookId, 1]
    );

    if (!webhook) {
      return {
        success: false,
        message: "Webhook not found or inactive",
        statusCode: 404,
      };
    }

    // Verify secret if provided
    if (webhook.secret) {
      const signature = headers["x-webhook-signature"] || headers["x-signature"];
      if (signature) {
        const expectedSignature = crypto
          .createHmac("sha256", webhook.secret)
          .update(JSON.stringify(body))
          .digest("hex");

        if (signature !== expectedSignature) {
          // Log failed attempt
          await query(
            `INSERT INTO webhook_logs (uid, webhook_id, method, event_type, payload, status, error) 
             VALUES (?, ?, ?, ?, ?, ?, ?)`,
            [
              webhook.uid,
              webhookId,
              method,
              headers["x-event-type"] || "unknown",
              JSON.stringify(body),
              "FAILED",
              "Invalid signature",
            ]
          );

          return {
            success: false,
            message: "Invalid signature",
            statusCode: 401,
          };
        }
      }
    }

    // Log successful webhook receipt
    await query(
      `INSERT INTO webhook_logs (uid, webhook_id, method, event_type, payload, status) 
       VALUES (?, ?, ?, ?, ?, ?)`,
      [
        webhook.uid,
        webhookId,
        method,
        headers["x-event-type"] || "unknown",
        JSON.stringify(body),
        "RECEIVED",
      ]
    );

    return {
      success: true,
      message: "Webhook received",
      uid: webhook.uid,
      data: body,
    };
  } catch (error) {
    console.error("Error handling webhook:", error);
    return {
      success: false,
      message: error.message,
      statusCode: 500,
    };
  }
}

/**
 * Get webhook logs
 */
async function getWebhookLogs(uid, webhookId = null, limit = 50) {
  try {
    let queryStr = `SELECT * FROM webhook_logs WHERE uid = ?`;
    const params = [uid];

    if (webhookId) {
      queryStr += ` AND webhook_id = ?`;
      params.push(webhookId);
    }

    queryStr += ` ORDER BY created_at DESC LIMIT ?`;
    params.push(limit);

    const logs = await query(queryStr, params);

    return {
      success: true,
      data: logs,
    };
  } catch (error) {
    console.error("Error fetching webhook logs:", error);
    return {
      success: false,
      message: error.message,
    };
  }
}

/**
 * Delete webhook logs
 */
async function deleteWebhookLogs(uid, webhookId = null) {
  try {
    let queryStr = `DELETE FROM webhook_logs WHERE uid = ?`;
    const params = [uid];

    if (webhookId) {
      queryStr += ` AND webhook_id = ?`;
      params.push(webhookId);
    }

    await query(queryStr, params);

    return {
      success: true,
      message: "Logs deleted successfully",
    };
  } catch (error) {
    console.error("Error deleting webhook logs:", error);
    return {
      success: false,
      message: error.message,
    };
  }
}

module.exports = {
  checkWebhook,
  getWebhooks,
  addWebhook,
  updateWebhook,
  deleteWebhook,
  handleWebhook,
  getWebhookLogs,
  deleteWebhookLogs,
};
