import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
import type { Table } from './table'
import type { Artifact } from '@/types/messages'

interface AppUser {
  login: string
}

interface AppConfig {
  xsrfCookieName: string
  user?: AppUser
  llmSettings?: {
    traceExplorerDefaultWebApp?: {
      projectKey?: string
      webAppId?: string
    }
  }
  dssExternalURL?: string
}

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

export const isLocal = () => {
  let dataikuLib: any
  try {
    /* global */ /* eslint-disable */ // @ts-ignore
    dataikuLib = dataiku /* eslint-enable */
  } catch {
    dataikuLib = undefined
  }

  return !dataikuLib
}

export function getAppConfig(): AppConfig | null {
  try {
    return (window as any).dkuUsageReportingUtils.getAppConfig() as AppConfig
  } catch (error) {
    console.error('Failed to fetch app config:', error)
    return null
  }
}

// Add utility function to get cookie value
export function getCookie(name: string): string | null {
  const value = `; ${document.cookie}`
  const parts = value.split(`; ${name}=`)
  if (parts.length === 2) return parts.pop()?.split(';').shift() || null
  return null
}

// Add utility function to get XSRF token
export function getXsrfToken(): string | null {
  const appConfig = getAppConfig()
  if (!appConfig?.xsrfCookieName) return null
  return getCookie(appConfig.xsrfCookieName)
}

// Export the AppConfig interface for use in other components
export type { AppConfig, AppUser }

export function toCsvString(tbl: Table): string {
  const escape = (val: unknown): string => {
    if (val === null || val === undefined) return ''
    const s = String(val)
    // Escape CSV per RFC 4180
    if (/[",\n\r]/.test(s)) return `"${s.replace(/"/g, '""')}"`
    return s
  }

  const header = tbl.columns.map(escape).join(',')
  const rows = (tbl.data ?? []).map((row) => {
    // Row can be shorter/longer than columns; normalize to columns length
    const arr = Array.isArray(row) ? row : []
    const normalized = tbl.columns.map((_, i) => escape(arr[i]))
    return normalized.join(',')
  })

  return [header, ...rows].join('\r\n')
}
export function extractRecordsFromArtifact(artifact: Artifact): Table[] {
  const records: Table[] = []
  for (const item of artifact.parts) {
    if (item['type'] === 'RECORDS') {
      records.push({ columns: item['records']['columns'], data: item['records']['data'] })
    }
  }
  return records
}
export function extractRecordsFromArtifacts(artifacts: Array<Artifact>) {
  const records: Record<string, Table[]> = {}
  for (const [i, a] of artifacts.entries()) {
    records[a.name + i] = extractRecordsFromArtifact(a)
  }
  return records
}
export function extractRecordsFromArtifactsFlat(artifacts: Array<Artifact>) {
  const records: Table[][] = []
  for (const a of artifacts) {
    records.push(extractRecordsFromArtifact(a))
  }
  return records
}
export function getRecordsRows(records: Table) {
  const rows: any[] = []
  if (!records.columns || !records.data) return rows
  for (const d of records.data) {
    const row: Record<string, any> = {}
    for (const [i, col] of records.columns.entries()) {
      row[col] = d[i]
    }
    rows.push(row)
  }
  return rows
}

export function getRecordsColumns(records: Table) {
  return records.columns?.map((col: string) => {
    return { name: col, label: col, field: col, align: 'left' }
  })
}

export function compareVersions(version1: string, version2: string): number {
  const splitVersion = (v: string) => v.split('.').map(Number)
  const [v1, v2] = [splitVersion(version1), splitVersion(version2)]

  for (let i = 0; i < Math.max(v1.length, v2.length); i++) {
    const num1 = v1[i] || 0
    const num2 = v2[i] || 0

    if (num1 > num2) return 1
    if (num1 < num2) return -1
  }
  return 0
}
