type OrderNotifyItem = {
  name: string
  quantity: number
  price?: number
}

export type OrderNotifyPayload = {
  orderId?: number
  orderNumber: string
  customerName?: string | null
  email?: string | null
  phone?: string | null
  transId?: string | null
  total: number
  shipping?: string | null
  note?: string | null
  items?: OrderNotifyItem[]
}

function telegramToken() {
  return (process.env.TELEGRAM_BOT_TOKEN || process.env.TELEGRAM_BOT_API || '').trim()
}

function telegramChatIds() {
  return (process.env.TELEGRAM_ALLOWED_CHAT_IDS || process.env.TELEGRAM_CHAT_ID || '')
    .split(/[\s,]+/)
    .map((value) => value.trim())
    .filter(Boolean)
}

function escapeHtml(value: string) {
  return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
}

function money(value: number) {
  return new Intl.NumberFormat('cs-CZ', {
    style: 'currency',
    currency: 'CZK',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  }).format(value)
}

function formatOrderMessage(title: string, order: OrderNotifyPayload) {
  const items = (order.items || [])
    .map((item) => {
      const line = item.price != null ? ` = ${money(item.price * item.quantity)}` : ''
      return `• ${escapeHtml(item.name)} × ${item.quantity}${line}`
    })
    .join('\n')

  return [
    `<b>${escapeHtml(title)}</b>`,
    `<code>#${escapeHtml(order.orderNumber)}</code> · ${money(Number(order.total) || 0)}`,
    '',
    order.customerName ? escapeHtml(order.customerName) : '',
    [order.email, order.phone].filter(Boolean).map((value) => escapeHtml(String(value))).join(' · '),
    order.shipping ? `<b>Doprava</b>: ${escapeHtml(order.shipping)}` : '',
    order.note ? `<b>Poznámka</b>: ${escapeHtml(order.note)}` : '',
    items ? `\n${items}` : '',
  ].filter((line, index, all) => line !== '' || all[index - 1] !== '').join('\n')
}

async function sendTelegramMessage(text: string, keyboard?: Array<Array<{ text: string; callback_data?: string; url?: string }>>) {
  const token = telegramToken()
  const chatIds = telegramChatIds()
  if (!token || !chatIds.length) {
    console.warn('[telegram] Přeskočeno: chybí TELEGRAM_BOT_TOKEN nebo TELEGRAM_ALLOWED_CHAT_IDS.')
    return
  }

  await Promise.all(chatIds.map(async (chatId) => {
    const response = await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        chat_id: chatId,
        text,
        parse_mode: 'HTML',
        disable_web_page_preview: true,
        reply_markup: keyboard?.length ? { inline_keyboard: keyboard } : undefined,
      }),
    })
    if (!response.ok) {
      const body = await response.text()
      console.error(`[telegram] sendMessage ${response.status}: ${body}`)
    }
  }))
}

export async function notifyNewOrder(order: OrderNotifyPayload) {
  try {
    const canSms = Boolean(order.orderId && order.transId && order.phone)
    const { buildSmsReminderUrl } = await import('@/lib/smsReminder')
    await sendTelegramMessage(
      formatOrderMessage('Nová objednávka (nezaplaceno)', order),
      canSms ? [[{ text: 'Odeslat SMS', url: buildSmsReminderUrl(Number(order.orderId)) }]] : undefined,
    )
  } catch (error) {
    console.error('[telegram] notifyNewOrder', error)
  }
}

export async function notifyPaidOrder(order: OrderNotifyPayload) {
  try {
    await sendTelegramMessage(formatOrderMessage('Objednávka zaplacena', order))
  } catch (error) {
    console.error('[telegram] notifyPaidOrder', error)
  }
}

type SqlConnection = {
  execute: (sql: string, values?: unknown[]) => Promise<[unknown, unknown]>
}

export async function notifyPaidOrderById(connection: SqlConnection, orderId: number) {
  try {
    const [orderRows] = await connection.execute(
      `SELECT o.order_number, o.total_price, o.note,
              oa.full_name, oa.email, oa.phone, os.method_name
       FROM orders o
       LEFT JOIN order_addresses oa ON oa.order_id = o.id AND oa.address_type = 'billing'
       LEFT JOIN order_shipping os ON os.order_id = o.id
       WHERE o.id = ?
       LIMIT 1`,
      [orderId]
    )
    const order = (orderRows as Array<{
      order_number: string
      total_price: number
      note: string | null
      full_name: string | null
      email: string | null
      phone: string | null
      method_name: string | null
    }>)[0]
    if (!order) return

    const [itemRows] = await connection.execute(
      `SELECT oi.product_name, oi.brand, oi.quantity, oi.unit_price, pv.volume_ml
       FROM order_items oi
       LEFT JOIN product_variants pv ON pv.id = oi.variant_id
       WHERE oi.order_id = ?`,
      [orderId]
    )

    await notifyPaidOrder({
      orderNumber: order.order_number,
      customerName: order.full_name,
      email: order.email,
      phone: order.phone,
      total: Number(order.total_price) || 0,
      shipping: order.method_name,
      note: order.note,
      items: (itemRows as Array<{
        product_name: string | null
        brand: string | null
        quantity: number
        unit_price: number
        volume_ml: number | null
      }>).map((item) => ({
        name: [item.brand, item.product_name, item.volume_ml ? `${item.volume_ml} ml` : ''].filter(Boolean).join(' · '),
        quantity: Number(item.quantity) || 0,
        price: Number(item.unit_price) || 0,
      })),
    })
  } catch (error) {
    console.error('[telegram] notifyPaidOrderById', error)
  }
}
