/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */

import { Request, Response } from 'express';
import catchAsync from '@/shared/utils/catchAsync';
import { leadWebhookService } from './webhook.service';
import { CaptureLead } from '../captureLeads/captureLeads.model';
import { getObjectId } from '@/shared/utils/commonHelper';

import responseCodes from '@/shared/utils/responseCode/responseCode';
import { IWebhookRequest } from './webhook.interface';
const { CaptureLeadResponseCodes } = responseCodes;

const extractLeadFields = (body: any) => {
  const nameRaw = (
    body.name ||
    body.fullName ||
    `${body.firstName ?? ''} ${body.lastName ?? ''}`
  ).trim();
  const [first, ...rest] = (nameRaw || '').split(' ').filter(Boolean);

  return {
    firstName: body.firstName || first || nameRaw || undefined,
    lastName: body.lastName || (rest.length ? rest.join(' ') : undefined),
    email: body.email || body.mail || undefined,
    phone: body.phone || body.mobile || body.contact || undefined,
    message: body.message || body.notes || body.comment || undefined,
    projectId: body.projectId || undefined,
    projectName: body.projectName || undefined,
    locality: body.locality || undefined,
    url: body.url || undefined,
  };
};

const safeJsonParseArray = (str: string): any[] | null => {
  if (typeof str !== 'string') return null;
  const trimmed = str.trim();
  if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) return null;

  try {
    const parsed = JSON.parse(trimmed);
    return Array.isArray(parsed) ? parsed : null;
  } catch {
    return null;
  }
};

const normalizeWebhookPayload = (body: any): any[] => {
  let payload = body;

  // Handle stringified 'leads' field safely
  if (payload?.leads && typeof payload.leads === 'string') {
    const parsedLeads = safeJsonParseArray(payload.leads);
    if (parsedLeads) return parsedLeads;
  }

  // Handle raw JSON string safely
  if (typeof payload === 'string') {
    const parsedLeads = safeJsonParseArray(payload);
    if (parsedLeads) return parsedLeads;
  }

  if (!Array.isArray(payload) && payload && typeof payload === 'object') {
    const { firstName, lastName, email, phone, message, projectId, projectName, locality, url } =
      extractLeadFields(payload);
    return [{ firstName, lastName, email, phone, message, projectId, projectName, locality, url }];
  }

  return Array.isArray(payload) ? payload : [];
};

const normalizeGoogleAdsPayload = (body: any): any[] => {
  console.log('🚀 ~ normalizeGoogleAdsPayload ~ body:', body);
  const columnData = body.user_column_data;
  console.log('🚀 ~ normalizeGoogleAdsPayload ~ columnData:', columnData);

  if (!columnData || !Array.isArray(columnData)) {
    console.warn('Google Ads Webhook body is missing user_column_data:', body);
    return [];
  }

  const rawLeadData: { [key: string]: string | undefined } = {};

  columnData.forEach((item: any) => {
    const columnId = item.column_id;
    const stringValue = item.string_value;

    if (columnId && stringValue) rawLeadData[columnId] = stringValue;
  });

  let firstName = rawLeadData['FIRST_NAME'];
  let lastName = rawLeadData['LAST_NAME'];
  const fullName = rawLeadData['FULL_NAME'];

  if (fullName && !firstName && !lastName) {
    const parts = fullName.trim().split(/\s+/);
    firstName = parts.shift();
    lastName = parts.join(' ');
  }

  const normalizedLead = {
    firstName: firstName || null,
    lastName: lastName || null,
    email: rawLeadData['EMAIL'] || null,
    phone: rawLeadData['PHONE_NUMBER']?.replace(/\D/g, '').slice(-10) || null, // currently targeting INDIA numbers only
    message: null,
    projectId: null,
    projectName: null,
    locality: null,
    url: null,
  };

  return [normalizedLead];
};

const processLeadWebhook = async ({
  companyId,
  captureLeadId,
  platform,
  req,
  res,
  isGoogleAds,
}) => {
  let webhookRequestDoc : IWebhookRequest;
  
  try {
    // Store webhook request in database
    webhookRequestDoc = await leadWebhookService.createWebhookRequest({
      companyId,
      method: req.method,
      url: req.originalUrl,
      headers: req.headers,
      body: req.body,
      query: req.query,
      params: req.params,
      ip: req.ip || req.connection.remoteAddress,
      userAgent: req.get('User-Agent'),
      status: 'received',
    });

    const captureLead = await CaptureLead.findById(getObjectId(captureLeadId));

    if (!captureLead || captureLead.isDeleted || !captureLead.isActive) {
      console.warn(
        `Integration ${captureLeadId} inactive or not found. Discarding lead.`,
      );
      
        // Update webhook request status
      await leadWebhookService.updateWebhookRequest(webhookRequestDoc.id, {
        status: 'failed',
        processingError: 'Integration inactive or not found'
      });
      
      return;
    }

    if (isGoogleAds) {
      const receivedKey = req.body['google_key'];
      const storedGoogleAdsWebhookKey = captureLead.googleAdsWebhookKey;

      if (!receivedKey || !storedGoogleAdsWebhookKey) {
        console.error(
          `Validation failed for ${companyId}: Key missing in request or DB.`,
        );
        
        // Update webhook request status
        await leadWebhookService.updateWebhookRequest(webhookRequestDoc.id, {
          status: 'failed',
          processingError: 'Validation failed: Key missing in request or DB'
        });
        
        return;
      }
    }

    const leadsPayload = isGoogleAds
      ? normalizeGoogleAdsPayload(req.body)
      : normalizeWebhookPayload(req.body);

    await leadWebhookService.bulkImportLeads({
      companyId,
      captureLead,
      leads: leadsPayload,
    });

    // Update webhook request status to processed
    await leadWebhookService.updateWebhookRequest(webhookRequestDoc.id, {
      status: 'processed'
    });

    console.log(
      `Leads for ${companyId} Imported Successfully from ${platform}`,
    );

    if (!isGoogleAds && !res.headersSent)
      res.success(
        true,
        CaptureLeadResponseCodes.SUCCESS,
        'Leads Imported Successfully',
      );
  } catch (error) {
    console.error(
      `Error processing ${platform} lead webhook in background:`,
      error,
    );
    
    // Update webhook request status to failed with error
    if (webhookRequestDoc) {
      await leadWebhookService.updateWebhookRequest(webhookRequestDoc.id, {
        status: 'failed',
        processingError: error instanceof Error ? error.message : 'Unknown error occurred'
      });
    }
  }
};

export const createLeadByWebhook = catchAsync(
  async (req: Request, res: Response) => {
    const { companyId, captureLeadId, platform } = req.params;
    const isGoogleAds = platform === 'google-ads';

    if (isGoogleAds) res.status(200).send('Webhook acknowledged by CRM');

    processLeadWebhook({
      companyId,
      captureLeadId,
      platform,
      req,
      res,
      isGoogleAds,
    });
  },
);
