import { reactive } from 'vue'

/**
 * Section classification for subscription grouping.
 * Maps item_group (legacy category) to display sections with icons.
 */
export const SECTION_MAP = {
  'Internet':     { match: ['Mensualités fibre', 'Mensualités sans fil', 'Internet camping', 'Adresse IP Fixe'], icon: 'language' },
  'Téléphonie':   { match: ['Téléphonie'], icon: 'phone' },
  'Télévision':   { match: ['Mensualités télévision'], icon: 'tv' },
  'Équipement':   { match: ['Installation et équipement fibre', 'Installation et équipement télé', 'Installation et équipement internet sans fil', 'Equipement internet fibre', 'Equipement internet sans fil', 'Location point à point', 'Quincaillerie'], icon: 'router' },
  'Hébergement':  { match: ['Hébergement', 'Nom de domaine', "Location d'espace", 'Location espace cloud'], icon: 'cloud' },
  'Rabais':       { match: ['Rabais'], icon: 'sell' },
}

const SECTION_ORDER = ['Internet', 'Téléphonie', 'Télévision', 'Équipement', 'Hébergement', 'Rabais', 'Autre']

/**
 * Classify a subscription into a section key.
 */
export function subSection (sub) {
  const price = parseFloat(sub.actual_price || 0)
  const group = (sub.item_group || '').trim()
  const sku = (sub.item_code || '').toUpperCase()
  const label = (sub.custom_description || sub.item_name || sub.plan_name || '').toLowerCase()

  // Negative price = rabais
  if (price < 0 || sku.startsWith('RAB') || label.includes('rabais')) return 'Rabais'

  // Match by item_group / service_category
  for (const [section, cfg] of Object.entries(SECTION_MAP)) {
    if (section === 'Rabais') continue
    if (cfg.match.some(m => group.includes(m))) return section
  }

  // Category-based matching (from Service Subscription.service_category)
  if (group === 'Internet') return 'Internet'
  if (group === 'VoIP' || group === 'Téléphonie') return 'Téléphonie'
  if (group === 'IPTV' || group === 'Télévision') return 'Télévision'
  if (group === 'Hébergement') return 'Hébergement'
  if (group === 'Bundle') return 'Internet'

  // SKU-based fallback (works for both legacy item_codes and SUB-* names)
  if (/^(FTTH|FTTB|TURBO|FIBRE|FORFERF|FORFBASE|FORFPERF|FORFPOP|FORFMES|SYM|VIP|ENT|COM|FIBCOM|HV)/.test(sku)) return 'Internet'
  if (/^(TELEP|FAX|SERV911|SERVTEL|TELE_)/.test(sku)) return 'Téléphonie'
  if (/^(TV|STB|RABTV)/.test(sku)) return 'Télévision'
  if (/^(LOC|FTT_H|FTTH_LOC)/.test(sku)) return 'Équipement'
  if (/^(HEB|DOM)/.test(sku)) return 'Hébergement'

  // Label-based fallback (Service Subscription plan_name)
  if (/fibre|internet|giga|illimit|turbo|optimum/i.test(label)) return 'Internet'
  if (/téléphon|voip|phone|fax|911/i.test(label)) return 'Téléphonie'
  if (/télé|tv|décodeur|stb/i.test(label)) return 'Télévision'
  if (/location|modem|routeur|appareil|frais.*accès/i.test(label)) return 'Équipement'
  if (/héberg|domaine|cloud|espace/i.test(label)) return 'Hébergement'

  return 'Autre'
}

export function isRebate (sub) {
  return parseFloat(sub.actual_price || sub.monthly_price || 0) < 0
}

export function subMainLabel (sub) {
  if (sub.custom_description && sub.custom_description.trim()) {
    return sub.custom_description
  }
  return sub.item_name || sub.plan_name || sub.item_code || sub.name
}

export function subSubLabel (sub) {
  if (sub.custom_description && sub.custom_description.trim()) return ''
  return ''
}

// Only Active subs contribute to the displayed monthly total. Cancelled/
// Suspended/Pending rows are still rendered (with strikethrough) for
// audit visibility but they shouldn't inflate the number the rep
// communicates to the customer. Was a real bug on C-LPB4: 5 internet
// rows summed to 196.05 because the 3 cancelled (Megafibre 80, TEST,
// FTTH100) were included in the math even though shown struck-through.
const isActiveBilling = sub => (sub.status || 'Active') === 'Active'

export function sectionTotal (items) {
  return items.reduce((s, sub) => isActiveBilling(sub) ? s + parseFloat(sub.actual_price || 0) : s, 0)
}

export function annualPrice (sub) {
  return parseFloat(sub.actual_price || 0) * 12
}

/**
 * Composable for managing subscription grouping, section state, and location-level helpers.
 * @param {import('vue').Ref<Array>} subscriptions - Reactive ref of all subscriptions
 */
export function useSubscriptionGroups (subscriptions) {
  const subSections = reactive({})   // { "locName:freq": { sectionKey: [subs] } }
  const openSections = reactive({})  // { "locName:sectionKey": true/false }

  function locSubs (locName) {
    return subscriptions.value.filter(s => s.service_location === locName)
  }

  function locSubsMonthly (locName) {
    return locSubs(locName).filter(s => s.billing_frequency !== 'A')
  }

  function locSubsAnnual (locName) {
    return locSubs(locName).filter(s => s.billing_frequency === 'A')
  }

  function locSubsMonthlyTotal (locName) {
    // Same active-only filter as sectionTotal — keep them in sync.
    return locSubsMonthly(locName).reduce((sum, s) => isActiveBilling(s) ? sum + parseFloat(s.actual_price || 0) : sum, 0)
  }

  function locSubsAnnualTotal (locName) {
    return locSubsAnnual(locName).reduce((sum, s) => isActiveBilling(s) ? sum + annualPrice(s) : sum, 0)
  }

  function locSubsSections (locName, freq) {
    const cacheKey = locName + ':' + freq
    if (!subSections[cacheKey]) {
      const subs = freq === 'A' ? locSubsAnnual(locName) : locSubsMonthly(locName)
      const groups = {}
      for (const sub of subs) {
        const sec = subSection(sub)
        if (!groups[sec]) groups[sec] = []
        groups[sec].push(sub)
      }
      for (const items of Object.values(groups)) {
        items.sort((a, b) => parseFloat(b.actual_price || 0) - parseFloat(a.actual_price || 0))
      }
      subSections[cacheKey] = groups
    }

    const result = []
    for (const key of SECTION_ORDER) {
      if (subSections[cacheKey][key]?.length) {
        result.push({ key, label: key, icon: SECTION_MAP[key]?.icon || 'label', items: subSections[cacheKey][key] })
      }
    }
    for (const [key, items] of Object.entries(subSections[cacheKey])) {
      if (!SECTION_ORDER.includes(key) && items.length) {
        result.push({ key, label: key, icon: SECTION_MAP[key]?.icon || 'label', items })
      }
    }
    return result
  }

  function sectionOpen (locName, sectionKey) {
    const k = locName + ':' + sectionKey
    if (openSections[k] === undefined) openSections[k] = false
    return openSections[k]
  }

  function toggleSection (locName, sectionKey) {
    const k = locName + ':' + sectionKey
    openSections[k] = !sectionOpen(locName, sectionKey)
  }

  function invalidateCache (locName) {
    delete subSections[locName + ':A']
    delete subSections[locName + ':M']
  }

  function invalidateAll () {
    for (const k of Object.keys(subSections)) delete subSections[k]
  }

  return {
    subSections,
    openSections,
    locSubs,
    locSubsMonthly,
    locSubsAnnual,
    locSubsMonthlyTotal,
    locSubsAnnualTotal,
    locSubsSections,
    sectionOpen,
    toggleSection,
    invalidateCache,
    invalidateAll,
  }
}
