import {
  getOrdersByIdsWithFullData,
  getOrderByIdWithFullData,
} from '@/src/dbService'
import { sendTelegramMessage } from '@/src/lib/telegram-service'
import { queueDataPusher } from '@/src/lib/queue-data-pusher'
import { ensureWorkerInit } from './worker-init';
import { getAppUrl } from '@/src/lib/env-exporter'

interface OrderIdMessage {
  orderIds: number[];
}

interface CancellationMessage {
  orderId: number;
  cancelledBy: 'user' | 'admin';
  reason: string;
  cancelledAt: string;
}

const formatDateTime = (dateStr: string | null | undefined): string => {
  if (!dateStr) return 'N/A';
  return new Date(dateStr).toLocaleString('en-IN', {
    dateStyle: 'medium',
    timeStyle: 'short',
    timeZone: 'Asia/Kolkata',
  });
};

const buildTelegramLinks = (orderId: number, userId?: number | null): string => {
  const baseUrl = getAppUrl() || 'https://ui.freshyo.in'
  const orderUrl = `${baseUrl}/manage-orders/order-details/${orderId}`
  const orderLink = `↪ <a href="${orderUrl}">Order</a>`
  if (!userId) {
    return orderLink
  }
  const userUrl = `${baseUrl}/user-management/${userId}`
  const userLink = `↪ <a href="${userUrl}">User</a>`
  return `${orderLink} | ${userLink}`
}

const formatOrderMessageWithFullData = (ordersData: any[]): string => {
  console.log('formatting the msg')
  let message = '🛒 <b>New Order Placed</b>\n\n';

  ordersData.forEach((order, index) => {
    message += `<b>Order ${order.id}</b>\n`;

    message += '📦 <b>Items:</b>\n';
    order.orderItems?.forEach((item: any) => {
      message += `  • ${item.product?.name || 'Unknown'} • ${item.product.productQuantity}${item.product.unit?.shortNotation}x${item.quantity}\n`;
    });

    message += `\n💰 <b>Total:</b> ₹${order.totalAmount}\n`;

    message += `🚚 <b>Delivery:</b> ${
      order.isFlashDelivery ? 'Flash Delivery' : formatDateTime(order.slot?.deliveryTime)
    }\n`;

    message += `\n📍 <b>Address:</b>\n`;
    message += `  ${order.address?.name || 'N/A'}\n`;
    message += `  ${order.address?.addressLine1 || ''}\n`;
    if (order.address?.addressLine2) {
      message += `  ${order.address.addressLine2}\n`;
    }
    message += `  ${order.address?.city || ''}, ${order.address?.state || ''} - ${order.address?.pincode || ''}\n`;
    if (order.address?.phone) {
      message += `  📞 ${order.address.phone}\n`;
    }

    message += `\n${buildTelegramLinks(order.id, order.userId)}\n`

    if (index < ordersData.length - 1) {
      message += '\n---\n\n';
    }
  });

  return message;
};

const formatCancellationMessage = (orderData: any, cancellationData: CancellationMessage): string => {
  const message = `❌ <b>Order Cancelled</b>

<b>Order #${orderData.id}</b>

👤 <b>Name:</b> ${orderData.address?.name || 'N/A'}
📞 <b>Phone:</b> ${orderData.address?.phone || 'N/A'}

📦 <b>Items:</b>
${orderData.orderItems?.map((item: any) => `  • ${item.product?.name || 'Unknown'} x${item.quantity}`).join('\n') || '  N/A'}

💰 <b>Total:</b> ₹${orderData.totalAmount}
💳 <b>Refund:</b> ${orderData.refundStatus === 'na' ? 'N/A (COD)' : orderData.refundStatus || 'Pending'}

❓ <b>Reason:</b> ${cancellationData.reason}
👤 <b>Cancelled by:</b> ${cancellationData.cancelledBy === 'admin' ? 'Admin' : 'User'}
 ⏰ <b>Time:</b> ${formatDateTime(cancellationData.cancelledAt)}

${buildTelegramLinks(orderData.id, orderData.userId)}
`;

  return message;
};

export const handleOrderPlaced = async (orderIds: number[], rawMessage?: string): Promise<void> => {
  try {
    const ordersData = await getOrdersByIdsWithFullData(orderIds)
    const telegramMessage = formatOrderMessageWithFullData(ordersData)
    await sendTelegramMessage(telegramMessage)
  } catch (error) {
    console.error('Failed to process order message:', error)
    const fallback = rawMessage ? `⚠️ Error parsing order: ${rawMessage}` : '⚠️ Error parsing order'
    await sendTelegramMessage(fallback)
  }
}

export const handleOrderCancelled = async (
  cancellationData: CancellationMessage,
  rawMessage?: string
): Promise<void> => {
  try {
    console.log('Order cancellation received, sending to Telegram...')
    const orderData = await getOrderByIdWithFullData(cancellationData.orderId)

    if (!orderData) {
      console.error('Order not found for cancellation:', cancellationData.orderId)
      await sendTelegramMessage(`⚠️ Order ${cancellationData.orderId} was cancelled but could not be found in database`)
      return
    }

    const refundStatus = orderData.refunds?.[0]?.refundStatus || 'pending'

    
    const telegramMessage = formatCancellationMessage({ ...orderData, refundStatus }, cancellationData)
    await sendTelegramMessage(telegramMessage)
  } catch (error) {
    console.error('Failed to process cancellation message:', error)
    const fallback = rawMessage ? `⚠️ Error processing cancellation: ${rawMessage}` : '⚠️ Error processing cancellation'
    await sendTelegramMessage(fallback)
  }
}

/**
 * Start the post order handler
 * Subscribes to the orders:placed channel and sends to Telegram
 */
export const publishOrder = async (orderDetails: OrderIdMessage): Promise<boolean> => {
  console.log('publishing order')
  try {
    await queueDataPusher.pushOrderPlacedQueue({
      name: 'order-placed',
      orderIds: orderDetails.orderIds,
    })
    return true;
  } catch (error) {
    console.error('Failed to publish order:', error);
    return false;
  }
};

export const publishFormattedOrder = async (
  createdOrders: any[],
  ordersBySlot: Map<number | null, any[]>
): Promise<boolean> => {
  try {
    const orderIds = createdOrders.map(order => order.id);
    return await publishOrder({ orderIds });
  } catch (error) {
    console.error('Failed to format and publish order:', error);
    return false;
  }
};

export const publishCancellation = async (
  orderId: number,
  cancelledBy: 'user' | 'admin',
  reason: string
): Promise<boolean> => {
  try {
    const message: CancellationMessage = {
      orderId,
      cancelledBy,
      reason,
      cancelledAt: new Date().toISOString(),
    };
    await queueDataPusher.pushOrderCancelledQueue({
      name: 'order-cancelled',
      ...message,
    })
    console.log('Cancellation published to queue:', orderId);
    return true;
  } catch (error) {
    console.error('Failed to publish cancellation:', error);
    return false;
  }
};
