import { describe, it, expect } from 'vitest'
import {
  toApiPath, subst, rows, mapTitle, mapBadge, mapMeta, manageLink,
  keyvalueFields, tableColumns, badges, panelVisible, tabSections,
} from './pluginAssetPanels'

const warrantyPanel = {
  id: 'warranty', title: 'Warranty', render: 'list',
  map: {
    title: 'vendor',
    badge: {
      label: 'status', color: 'statuscolor',
      labelmap: { active: 'Active', expired: 'Expired' },
    },
    meta: [
      { key: 'servicelevel' },
      { key: 'enddate', label: 'Ends', format: 'date' },
      { key: 'servicetag', label: 'Tag', mono: true },
    ],
  },
  empty: 'No warranty on record.',
  manage: { to: '/warranties?addfor={assetid}', label: 'Add / manage' },
  _data: [
    {
      vendor: 'Dell', status: 'active', statuscolor: '#4CAF50',
      servicelevel: 'ProSupport', enddate: '2027-01-01', servicetag: 'ABC123',
    },
  ],
}

describe('endpoint + subst', () => {
  it('substitutes {assetid} and strips the leading /api', () => {
    expect(toApiPath('/api/warranty/asset/{assetid}', 5)).toBe('/warranty/asset/5')
    expect(subst('/warranties?addfor={assetid}', 9)).toBe('/warranties?addfor=9')
  })
  it('only strips a leading /api segment, not /apixyz', () => {
    expect(toApiPath('/apixyz/thing', 1)).toBe('/apixyz/thing')
  })
})

describe('list render mapping (warranty)', () => {
  it('maps title, badge (labelmap + color), and formatted meta', () => {
    const item = rows(warrantyPanel)[0]
    expect(mapTitle(warrantyPanel, item)).toBe('Dell')

    const badge = mapBadge(warrantyPanel, item)
    expect(badge.label).toBe('Active')
    expect(badge.color).toBe('#4CAF50')

    const meta = mapMeta(warrantyPanel, item)
    expect(meta[0].text).toBe('ProSupport')
    expect(meta[1].text).toMatch(/^Ends /)      // date formatted + labelled
    expect(meta[2]).toEqual({ text: 'Tag ABC123', mono: true })
  })

  it('drops empty meta values', () => {
    const item = { vendor: 'HP', status: 'expired', statuscolor: '#F44336' }
    const meta = mapMeta(warrantyPanel, { ...item })
    expect(meta).toEqual([])   // no servicelevel/enddate/servicetag
    expect(mapBadge(warrantyPanel, item).label).toBe('Expired')
  })

  it('builds the manage link with the assetid', () => {
    expect(manageLink(warrantyPanel, 7)).toBe('/warranties?addfor=7')
  })

  it('is visible when it has rows or an empty message', () => {
    expect(panelVisible(warrantyPanel)).toBe(true)
    expect(panelVisible({ ...warrantyPanel, _data: [] })).toBe(true)  // has empty
    expect(panelVisible({ render: 'list', _data: [] })).toBe(false)
  })
})

describe('keyvalue + table + badge', () => {
  it('keyvalue reads a fields array or a plain object', () => {
    const fromFields = keyvalueFields({
      render: 'keyvalue', _data: { fields: [{ label: 'Cal due', value: '2026-01-01', format: 'date' }] },
    })
    expect(fromFields[0].label).toBe('Cal due')

    const fromObject = keyvalueFields({ render: 'keyvalue', _data: { hostname: 'PC1', online: true } })
    expect(fromObject).toEqual([
      { label: 'Hostname', value: 'PC1' },
      { label: 'Online', value: 'Yes' },
    ])
  })

  it('table uses declared columns, else infers from row keys', () => {
    const declared = tableColumns({ columns: [{ key: 'a', label: 'Alpha' }], _data: [{ a: 1 }] })
    expect(declared).toEqual([{ key: 'a', label: 'Alpha' }])

    const inferred = tableColumns({ _data: [{ vendor: 'x', model: 'y' }] })
    expect(inferred.map((c) => c.label)).toEqual(['Vendor', 'Model'])
  })

  it('badge reads an array or a badges field', () => {
    expect(badges({ render: 'badge', _data: [{ label: 'A', color: '#111' }] })).toEqual([{ label: 'A', color: '#111' }])
    expect(badges({ render: 'badge', _data: { badges: [{ label: 'B', color: '#222' }] } })).toEqual([{ label: 'B', color: '#222' }])
  })
})

describe('tabSections', () => {
  const panel = {
    render: 'tabs',
    _data: {
      sections: [
        { label: 'General', fields: [{ label: 'Cnc', value: 'OKUMA' }] },
        { label: 'eFocas', fields: [{ label: 'IpAddr', value: '192.168.1.1', mono: true }] },
        // A section whose fields all dropped out must not leave an empty tab.
        { label: 'NTSHR', fields: [] },
      ],
    },
  }

  it('returns one entry per non-empty section', () => {
    expect(tabSections(panel).map((s) => s.label)).toEqual(['General', 'eFocas'])
  })

  it('formats field values and carries mono through', () => {
    const efocas = tabSections(panel)[1]
    expect(efocas.fields[0]).toEqual({ label: 'IpAddr', value: '192.168.1.1', mono: true })
  })

  it('is empty for a payload with no sections', () => {
    expect(tabSections({ render: 'tabs', _data: null })).toEqual([])
  })

  it('drives panel visibility', () => {
    expect(panelVisible(panel)).toBe(true)
    expect(panelVisible({ render: 'tabs', _data: { sections: [] } })).toBe(false)
  })
})
