/**
 * Prompt Utilities
 *
 * Provides functions for:
 * - Loading system prompts and greeting messages from database
 * - Formatting opening hours for different languages
 * - Building complete system prompts with opening hours
 */

import { SupabaseClient } from 'https://esm.sh/@supabase/supabase-js@2'

export interface SystemPrompt {
  languageCode: string
  systemPrompt: string
  greetingMessage: string
}

export interface DailyHours {
  is_open: boolean
  open: string
  close: string
}

export interface BusinessHours {
  monday: DailyHours
  tuesday: DailyHours
  wednesday: DailyHours
  thursday: DailyHours
  friday: DailyHours
  saturday: DailyHours
  sunday: DailyHours
}

export interface SpecialHours {
  date: string
  opening_time: string | null
  closing_time: string | null
  is_closed: boolean
  note: string | null
}

// Day name translations
const DAY_NAMES: Record<string, Record<string, string>> = {
  hu: {
    monday: 'Hétfő',
    tuesday: 'Kedd',
    wednesday: 'Szerda',
    thursday: 'Csütörtök',
    friday: 'Péntek',
    saturday: 'Szombat',
    sunday: 'Vasárnap'
  },
  en: {
    monday: 'Monday',
    tuesday: 'Tuesday',
    wednesday: 'Wednesday',
    thursday: 'Thursday',
    friday: 'Friday',
    saturday: 'Saturday',
    sunday: 'Sunday'
  },
  de: {
    monday: 'Montag',
    tuesday: 'Dienstag',
    wednesday: 'Mittwoch',
    thursday: 'Donnerstag',
    friday: 'Freitag',
    saturday: 'Samstag',
    sunday: 'Sonntag'
  }
}

// Labels for opening hours sections
const LABELS: Record<string, Record<string, string>> = {
  hu: {
    openingHours: 'Nyitvatartás',
    specialHours: 'Speciális nyitvatartás',
    closed: 'zárva',
    from: 'órától',
    to: 'óráig'
  },
  en: {
    openingHours: 'Opening hours',
    specialHours: 'Special opening hours',
    closed: 'closed',
    from: 'from',
    to: 'to'
  },
  de: {
    openingHours: 'Öffnungszeiten',
    specialHours: 'Sonderöffnungszeiten',
    closed: 'geschlossen',
    from: 'von',
    to: 'bis'
  }
}

// Transfer phone number sentences (only shown during open hours)
const TRANSFER_PHONE_SENTENCES: Record<string, string> = {
  hu: 'Hogyha az ügyfél humán kollégával szeretne beszélni, akkor kapcsold át nyitvatartási időben a következő telefonszámra: ${phone_number}',
  en: 'If the customer would like to speak with a human colleague, transfer them to the following phone number during opening hours: ${phone_number}',
  de: 'Wenn der Kunde mit einem menschlichen Kollegen sprechen möchte, leiten Sie ihn während der Öffnungszeiten an folgende Telefonnummer weiter: ${phone_number}'
}

/**
 * Format time string (HH:MM) to localized format
 * For Hungarian: returns just the hour number (e.g., "9" or "16")
 * For English: returns 12-hour format (e.g., "9 am" or "4 pm")
 * For German: returns 24-hour format (e.g., "09:00")
 */
function formatTime(time: string, languageCode: string): string {
  const [hours, minutes] = time.split(':')
  const hour = parseInt(hours, 10)

  if (languageCode === 'hu') {
    // For Hungarian, just return the hour number (no leading zero, no minutes if :00)
    if (minutes === '00') {
      return `${hour}`
    }
    return `${hour}:${minutes}`
  }

  if (languageCode === 'en') {
    // 12-hour format for English
    const period = hour >= 12 ? 'pm' : 'am'
    const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour
    return minutes === '00' ? `${hour12} ${period}` : `${hour12}:${minutes} ${period}`
  }

  // 24-hour format for German
  return `${hours}:${minutes}`
}

/**
 * Format a date string (YYYY-MM-DD) to localized format
 */
function formatDate(dateStr: string, languageCode: string): string {
  const [year, month, day] = dateStr.split('-')

  if (languageCode === 'hu') {
    return `${year}. ${month}. ${day}.`
  } else if (languageCode === 'de') {
    return `${day}.${month}.${year}`
  } else {
    // English: Month Day, Year
    const date = new Date(dateStr)
    const monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November', 'December']
    return `${monthNames[date.getMonth()]} ${parseInt(day, 10)}, ${year}`
  }
}

/**
 * Load system prompt and greeting message from database
 *
 * @param supabase - Supabase client
 * @param languageCode - Language code (hu, en, de)
 * @returns SystemPrompt object or null if not found
 */
export async function loadSystemPrompt(
  supabase: SupabaseClient,
  languageCode: string = 'hu'
): Promise<SystemPrompt | null> {
  console.log(`[PromptUtils] Loading prompts for language: ${languageCode}`)

  const { data: prompts, error } = await supabase
    .from('system_default_prompts')
    .select('prompt_type, content')
    .eq('language_code', languageCode)

  if (error) {
    console.error('[PromptUtils] Error loading prompts:', error)
    return null
  }

  if (!prompts || prompts.length === 0) {
    console.error(`[PromptUtils] No prompts found for language: ${languageCode}`)
    // Fall back to Hungarian if the requested language is not found
    if (languageCode !== 'hu') {
      console.log('[PromptUtils] Falling back to Hungarian prompts')
      return loadSystemPrompt(supabase, 'hu')
    }
    return null
  }

  const systemPrompt = prompts.find(p => p.prompt_type === 'system_prompt')?.content || ''
  const greetingMessage = prompts.find(p => p.prompt_type === 'greeting_message')?.content || ''

  return {
    languageCode,
    systemPrompt,
    greetingMessage
  }
}

/**
 * Format business hours for display in system prompt
 *
 * @param businessHours - Business hours object
 * @param languageCode - Language code for localization
 * @returns Formatted opening hours string
 *
 * Format examples:
 * - Hungarian: "Hétfő: 9 órától 16 óráig" or "Szombat: zárva"
 * - English: "Monday: 9 am to 4 pm" or "Saturday: closed"
 * - German: "Montag: 09:00 bis 16:00" or "Samstag: geschlossen"
 */
export function formatBusinessHours(
  businessHours: BusinessHours | null,
  languageCode: string = 'hu'
): string {
  if (!businessHours) return ''

  const dayNames = DAY_NAMES[languageCode] || DAY_NAMES['en']
  const labels = LABELS[languageCode] || LABELS['en']
  const dayOrder = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']

  const lines: string[] = []

  for (const day of dayOrder) {
    const hours = businessHours[day as keyof BusinessHours]
    const dayName = dayNames[day]

    if (!hours || !hours.is_open) {
      lines.push(`${dayName}: ${labels.closed}`)
    } else {
      const openTime = formatTime(hours.open, languageCode)
      const closeTime = formatTime(hours.close, languageCode)

      if (languageCode === 'hu') {
        // Hungarian format: "Hétfő: 9 órától 16 óráig"
        lines.push(`${dayName}: ${openTime} ${labels.from} ${closeTime} ${labels.to}`)
      } else if (languageCode === 'en') {
        // English format: "Monday: 9 am to 4 pm"
        lines.push(`${dayName}: ${openTime} ${labels.to} ${closeTime}`)
      } else {
        // German format: "Montag: 09:00 bis 16:00"
        lines.push(`${dayName}: ${openTime} ${labels.to} ${closeTime}`)
      }
    }
  }

  return lines.join('\n')
}

/**
 * Format special hours for display in system prompt
 *
 * @param specialHours - Array of special hours
 * @param languageCode - Language code for localization
 * @returns Formatted special hours string or empty string if no special hours
 *
 * Format examples:
 * - Hungarian: "2025-12-04 10 órától 13 óráig (Karácsony)" or "2025-12-25 zárva (Karácsony)"
 * - English: "December 4, 2025: 10 am to 1 pm (Christmas)" or "December 25, 2025: closed (Christmas)"
 * - German: "04.12.2025: 10:00 bis 13:00 (Weihnachten)" or "25.12.2025: geschlossen (Weihnachten)"
 */
export function formatSpecialHours(
  specialHours: SpecialHours[] | null,
  languageCode: string = 'hu'
): string {
  if (!specialHours || specialHours.length === 0) return ''

  const labels = LABELS[languageCode] || LABELS['en']
  const lines: string[] = []

  // Filter out past dates
  const today = new Date().toISOString().split('T')[0]
  const futureHours = specialHours.filter(sh => sh.date >= today)

  if (futureHours.length === 0) return ''

  for (const special of futureHours) {
    // For Hungarian, use simple YYYY-MM-DD format; for others use localized date format
    const dateStr = languageCode === 'hu' ? special.date : formatDate(special.date, languageCode)
    // Add note/comment if provided (e.g., "Karácsony", "Christmas")
    const noteStr = special.note ? ` (${special.note})` : ''

    if (special.is_closed) {
      if (languageCode === 'hu') {
        lines.push(`${dateStr} ${labels.closed}${noteStr}`)
      } else {
        lines.push(`${dateStr}: ${labels.closed}${noteStr}`)
      }
    } else if (special.opening_time && special.closing_time) {
      const openTime = formatTime(special.opening_time, languageCode)
      const closeTime = formatTime(special.closing_time, languageCode)

      if (languageCode === 'hu') {
        // Hungarian format: "2025-12-04 10 órától 13 óráig (Karácsony)"
        lines.push(`${dateStr} ${openTime} ${labels.from} ${closeTime} ${labels.to}${noteStr}`)
      } else if (languageCode === 'en') {
        // English format: "December 4, 2025: 10 am to 1 pm (Christmas)"
        lines.push(`${dateStr}: ${openTime} ${labels.to} ${closeTime}${noteStr}`)
      } else {
        // German format: "04.12.2025: 10:00 bis 13:00 (Weihnachten)"
        lines.push(`${dateStr}: ${openTime} ${labels.to} ${closeTime}${noteStr}`)
      }
    }
  }

  return lines.join('\n')
}

/**
 * Build complete opening hours section for system prompt
 *
 * @param businessHours - Business hours object
 * @param specialHours - Array of special hours
 * @param languageCode - Language code for localization
 * @returns Complete opening hours section string
 */
export function buildOpeningHoursSection(
  businessHours: BusinessHours | null,
  specialHours: SpecialHours[] | null,
  languageCode: string = 'hu'
): string {
  const labels = LABELS[languageCode] || LABELS['en']
  const sections: string[] = []

  // Regular hours
  const regularHours = formatBusinessHours(businessHours, languageCode)
  if (regularHours) {
    sections.push(`${labels.openingHours}:\n${regularHours}`)
  }

  // Special hours (only future ones)
  const specialHoursText = formatSpecialHours(specialHours, languageCode)
  if (specialHoursText) {
    sections.push(`${labels.specialHours}:\n${specialHoursText}`)
  }

  return sections.join('\n\n')
}

/**
 * Replace template variables in prompt
 *
 * @param template - Prompt template with ${variable} placeholders
 * @param variables - Object with variable values
 * @returns Prompt with variables replaced
 */
export function replacePromptVariables(
  template: string,
  variables: Record<string, string>
): string {
  let result = template

  for (const [key, value] of Object.entries(variables)) {
    result = result.replace(new RegExp(`\\$\\{${key}\\}`, 'g'), value)
  }

  return result
}

/**
 * Build the transfer phone number sentence
 *
 * @param transferPhoneNumber - Phone number to transfer to (international format)
 * @param languageCode - Language code for localization
 * @returns Formatted transfer phone sentence or empty string if no phone number
 */
export function buildTransferPhoneSentence(
  transferPhoneNumber: string | null | undefined,
  languageCode: string = 'hu'
): string {
  if (!transferPhoneNumber || transferPhoneNumber.trim() === '') {
    return ''
  }

  const template = TRANSFER_PHONE_SENTENCES[languageCode] || TRANSFER_PHONE_SENTENCES['hu']
  return template.replace('${phone_number}', transferPhoneNumber.trim())
}

/**
 * Build complete system prompt with opening hours appended
 *
 * @param basePrompt - Base system prompt template
 * @param storeName - Store name
 * @param storeId - Store ID
 * @param businessHours - Business hours object
 * @param specialHours - Array of special hours
 * @param languageCode - Language code for localization
 * @param transferPhoneNumber - Optional phone number for human transfer during open hours
 * @returns Complete system prompt
 */
export function buildCompleteSystemPrompt(
  basePrompt: string,
  storeName: string,
  storeId: string,
  businessHours: BusinessHours | null,
  specialHours: SpecialHours[] | null,
  languageCode: string = 'hu',
  transferPhoneNumber?: string | null
): string {
  // Replace variables in the base prompt
  let prompt = replacePromptVariables(basePrompt, {
    storeName,
    storeId
  })

  // Build and append opening hours section
  const openingHoursSection = buildOpeningHoursSection(businessHours, specialHours, languageCode)

  if (openingHoursSection) {
    prompt += `\n\n--------------------------------------------------\n${openingHoursSection}`
  }

  // Add transfer phone number sentence if provided (only when business hours are enabled)
  if (transferPhoneNumber && businessHours) {
    const transferSentence = buildTransferPhoneSentence(transferPhoneNumber, languageCode)
    if (transferSentence) {
      prompt += `\n\n${transferSentence}`
    }
  }

  return prompt
}

/**
 * Load store's business hours from database
 *
 * @param supabase - Supabase client
 * @param storeId - Store ID
 * @returns Business hours or null
 */
export async function loadStoreBusinessHours(
  supabase: SupabaseClient,
  storeId: string
): Promise<{ businessHours: BusinessHours | null; isEnabled: boolean }> {
  const { data, error } = await supabase
    .from('store_business_hours')
    .select('daily_hours, is_enabled')
    .eq('store_id', storeId)
    .single()

  if (error || !data) {
    console.log(`[PromptUtils] No business hours found for store: ${storeId}`)
    return { businessHours: null, isEnabled: false }
  }

  return {
    businessHours: data.daily_hours as BusinessHours,
    isEnabled: data.is_enabled
  }
}

/**
 * Load store's special hours from database (future dates only)
 *
 * @param supabase - Supabase client
 * @param storeId - Store ID
 * @returns Array of special hours or empty array
 */
export async function loadStoreSpecialHours(
  supabase: SupabaseClient,
  storeId: string
): Promise<SpecialHours[]> {
  const today = new Date().toISOString().split('T')[0]

  const { data, error } = await supabase
    .from('store_special_hours')
    .select('date, opening_time, closing_time, is_closed, note')
    .eq('store_id', storeId)
    .gte('date', today)
    .order('date', { ascending: true })

  if (error) {
    console.error(`[PromptUtils] Error loading special hours for store ${storeId}:`, error)
    return []
  }

  return data || []
}
