// Общие помощники UI задач: подписи статусов, приоритеты, Markdown.
// Все строки — через vue-i18n (i18n.global), локаль переключается реактивно.

import DOMPurify from 'dompurify'
import { marked } from 'marked'
import i18n from './i18n'
import { intlLocale } from './i18n/locale'

function t(key: string, params?: Record<string, unknown>): string {
  return i18n.global.t(key, params ?? {})
}

// Название сервиса — шапка, тайтлы вкладок
export const APP_NAME = 'GNexus Tasks'

// Тайтл вкладки: «{страница} — GNexus Tasks»; без части — просто название сервиса
export function setPageTitle(page?: string): void {
  document.title = page ? `${page} — ${APP_NAME}` : APP_NAME
}

// Ключ отсутствует в словаре (неизвестный код статуса) → отдаём код как есть
function tOr(key: string, fallback: string): string {
  return i18n.global.te(key) ? i18n.global.t(key) : fallback
}

export function statusLabel(status: string): string {
  return tOr(`taskui.status.${status}`, status)
}

export const STATUS_VARIANTS: Record<string, string> = {
  to_do: 'info',
  in_progress: 'accent',
  done: 'success',
  cancelled: 'error',
  deferred: 'warning',
}

export function statusVariant(status: string): string {
  return STATUS_VARIANTS[status] ?? 'neutral'
}

// Иконка статуса — согласована со счётчиками статистики (ph-square / ph-circle-half / …)
export const STATUS_ICONS: Record<string, string> = {
  to_do: 'ph-square',
  in_progress: 'ph-circle-half',
  done: 'ph-check-circle',
  cancelled: 'ph-x-circle',
  deferred: 'ph-pause-circle',
}

export function statusIcon(status: string): string {
  return STATUS_ICONS[status] ?? 'ph-square'
}

export function relevanceLabel(status: string): string {
  return tOr(`taskui.relevance.${status}`, status)
}

// Приоритет — понятная 5-градусная шкала с цветом; в БД хранится число 0–10.
// very_low 0–2 · low 3–4 · medium 5–6 · high 7–8 · urgent 9–10.
export type PriorityGrade = 'very_low' | 'low' | 'medium' | 'high' | 'urgent'

export function priorityToGrade(priority: number): PriorityGrade {
  if (priority <= 2) return 'very_low'
  if (priority <= 4) return 'low'
  if (priority <= 6) return 'medium'
  if (priority <= 8) return 'high'
  return 'urgent'
}

export function gradeToPriority(grade: string): number {
  const map: Record<PriorityGrade, number> = { very_low: 1, low: 3, medium: 5, high: 7, urgent: 9 }
  return map[grade as PriorityGrade] ?? 5
}

export function priorityLabel(priority: number): string {
  return t(`taskui.priority.${priorityToGrade(priority)}`)
}

export function priorityVariant(priority: number): string {
  const variants: Record<PriorityGrade, string> = {
    very_low: 'neutral',
    low: 'info',
    medium: 'primary',
    high: 'warning',
    urgent: 'error',
  }
  return variants[priorityToGrade(priority)]
}

export function priorityOptions(): { value: string; label: string }[] {
  return (['very_low', 'low', 'medium', 'high', 'urgent'] as PriorityGrade[]).map((g) => ({
    value: g,
    label: t(`taskui.priority.${g}`),
  }))
}

// Опции статусов для GnSelect (в видах оборачивать в computed)
export function statusOptions(): { value: string; label: string }[] {
  return ['to_do', 'in_progress', 'done', 'cancelled', 'deferred'].map((s) => ({
    value: s,
    label: t(`taskui.status.${s}`),
  }))
}

export function renderMarkdown(text: string): string {
  return DOMPurify.sanitize(marked.parse(text, { async: false }))
}

// «90» → «1 ч 30 м»; для чипов оценок времени
export function formatMinutes(minutes: number | null): string {
  if (minutes === null) return ''
  const h = Math.floor(minutes / 60)
  const m = minutes % 60
  if (h && m) return t('taskui.time.hm', { h, m })
  if (h) return t('taskui.time.h', { h })
  return t('taskui.time.m', { m })
}

// Валюта бюджетов — глобальная настройка, выбирается один раз и применяется всюду
export function currencyOptions(): { value: string; label: string }[] {
  return ['UAH', 'USD', 'EUR', 'GBP', 'PLN'].map((c) => ({
    value: c,
    label: t(`taskui.currency.${c}`),
  }))
}

const CURRENCY_SYMBOLS: Record<string, string> = {
  UAH: '₴',
  USD: '$',
  EUR: '€',
  GBP: '£',
  PLN: 'zł',
}

let activeCurrency = 'UAH'

export function setCurrency(currency: string): void {
  activeCurrency = currency
}

export function currencySymbol(): string {
  return CURRENCY_SYMBOLS[activeCurrency] ?? activeCurrency
}

// «5 000 ₴» — суммы задач; валюта берётся из глобальной настройки
export function formatMoney(amount: number | null): string {
  if (amount === null) return ''
  return `${amount.toLocaleString(intlLocale())} ${currencySymbol()}`
}

// --- Дедлайны и регулярность (ТЗ 3.4, 3.5) ---

export const DEADLINE_PERIOD_VALUES = ['day', 'week', 'month', 'year'] as const

export function deadlinePeriodOptions(): { value: string; label: string }[] {
  return DEADLINE_PERIOD_VALUES.map((p) => ({ value: p, label: t(`taskui.deadline.${p}`) }))
}

export const RECUR_KIND_VALUES = ['interval', 'weekdays', 'monthly'] as const

export function recurKindOptions(): { value: string; label: string }[] {
  return RECUR_KIND_VALUES.map((k) => ({
    value: k,
    label: t(`taskui.recur.kind.${k}`),
  }))
}

// Короткое имя дня недели через Intl: 2024-01-01 — понедельник (ISO: пн=1..вс=7)
export function weekdayShort(isoWeekday: number): string {
  const d = new Date(2024, 0, 7 + isoWeekday)
  return new Intl.DateTimeFormat(intlLocale(), { weekday: 'short' }).format(d)
}

// Дата дедлайна в локали: ru → «19.09.2026», en → «09/19/2026»
export function formatDate(isoDate: string): string {
  return new Intl.DateTimeFormat(intlLocale(), {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).format(new Date(isoDate))
}

export function deadlineLabel(task: { deadline_date: string | null; deadline_period: string | null }): string {
  if (task.deadline_date) return t('taskui.deadline.until', { date: formatDate(task.deadline_date) })
  const period = task.deadline_period ?? ''
  return i18n.global.te(`taskui.deadline.${period}`)
    ? t(`taskui.deadline.${period}`)
    : ''
}

export function deadlineOverdue(task: { deadline_date: string | null }): boolean {
  if (!task.deadline_date) return false
  const today = new Date().toISOString().slice(0, 10)
  return task.deadline_date < today
}

export function recurrenceLabel(task: {
  recur_kind: string | null
  recur_interval_days: number | null
  recur_weekdays: string | null
  recur_day_of_month: number | null
}): string {
  if (task.recur_kind === 'interval') {
    const step = task.recur_interval_days ?? 1
    if (step === 1) return t('taskui.recur.daily')
    if (step === 7) return t('taskui.recur.weekly')
    return t('taskui.recur.everyN', { n: step })
  }
  if (task.recur_kind === 'weekdays') {
    if (!task.recur_weekdays) return t('taskui.recur.byWeekdays')
    return task.recur_weekdays
      .split(',')
      .map((d) => weekdayShort(Number(d)))
      .join(' ')
  }
  if (task.recur_kind === 'monthly') {
    return t('taskui.recur.monthlyDay', { day: task.recur_day_of_month ?? '' })
  }
  return ''
}

// «бюджет 5 000 ₴ / оценка 2 000 ₴» — бейджи в видах
export function budgetBadge(task: { budget_money: number | null; cost_estimate_money: number | null }): string {
  if (task.budget_money === null) return ''
  const parts = [t('taskui.money.budget', { amount: formatMoney(task.budget_money) })]
  if (task.cost_estimate_money !== null) {
    parts.push(t('taskui.money.estimate', { amount: formatMoney(task.cost_estimate_money) }))
  }
  return parts.join(' / ')
}

// Подписи чернового предложения LLM (стек, страница задачи)
export function proposalItems(task: {
  ai_proposal: import('./api').AiProposal | null
}): { icon: string; label: string }[] {
  const p = task.ai_proposal
  if (!p) return []
  const items: { icon: string; label: string }[] = []
  p.tags.forEach((tag) => items.push({ icon: 'ph-tag', label: tag }))
  if (p.project)
    items.push({
      icon: 'ph-folder',
      label: p.new_project ? t('stack.proposalNewProject', { name: p.project }) : p.project,
    })
  if (p.priority !== null)
    items.push({ icon: 'ph-flag', label: t('stack.proposalPriority', { n: p.priority }) })
  if (p.estimated_minutes !== null && p.estimated_minutes !== undefined)
    items.push({ icon: 'ph-timer', label: `≈ ${formatMinutes(p.estimated_minutes)}` })
  return items
}