import { calculateExercise } from '../utils/patCalculations'
import { supabase } from './supabaseClient'

const hydrateExercise = (exercise = {}) => {
  const normalized = {
    name: exercise.name || '',
    soll: exercise.soll ?? 0,
    faktor: exercise.faktor ?? 0
  }

  if (exercise.subA && exercise.subB) {
    normalized.subA = exercise.subA
    normalized.subB = exercise.subB
    if (exercise.subLabels) {
      normalized.subLabels = exercise.subLabels
    }
  } else {
    normalized.values = exercise.values || []
  }

  const { durchschnitt, points } = calculateExercise({
    ...normalized,
    values: normalized.values || []
  })

  return {
    ...normalized,
    durchschnitt,
    points
  }
}

const mapSharedAssessment = (row) => ({
  id: row.id,
  patType: row.pat_type,
  datum: row.datum,
  name: row.name,
  exercises: (row.exercises || []).map(hydrateExercise)
})

const getSingleRow = (data) => (Array.isArray(data) ? data[0] || null : data || null)

const buildShareUrl = (shareToken) => {
  if (typeof window === 'undefined') {
    return `?share=${shareToken}`
  }

  const url = new URL(window.location.origin + window.location.pathname)
  url.searchParams.set('share', shareToken)
  return url.toString()
}

const mapShareError = (error) => {
  const message = error?.message || ''

  if (message.includes('Tests are hidden in the profile')) {
    return new Error('Deine Tests sind im Profil aktuell nicht sichtbar.')
  }

  return error
}

export const createAssessmentShareLink = async (assessment) => {
  if (!assessment) {
    throw new Error('Kein Test zum Teilen gefunden.')
  }

  if (!supabase) {
    throw new Error('Supabase ist nicht konfiguriert.')
  }

  const { data, error } = await supabase.rpc('create_or_get_assessment_share', {
    p_assessment_id: assessment.id
  })

  if (error) throw mapShareError(error)

  const row = getSingleRow(data)
  if (!row?.share_token) {
    throw new Error('Kein Freigabetoken erhalten.')
  }

  return {
    token: row.share_token,
    url: buildShareUrl(row.share_token)
  }
}

export const listAssessmentShares = async (assessmentIds = []) => {
  if (!supabase) {
    throw new Error('Supabase ist nicht konfiguriert.')
  }

  if (!assessmentIds.length) {
    return {}
  }

  const { data, error } = await supabase
    .from('assessment_shares')
    .select('assessment_id, share_token')
    .in('assessment_id', assessmentIds)

  if (error) throw error

  return (data || []).reduce((acc, row) => {
    acc[row.assessment_id] = row.share_token
    return acc
  }, {})
}

export const revokeAssessmentShare = async (assessmentId) => {
  if (!supabase) {
    throw new Error('Supabase ist nicht konfiguriert.')
  }

  const { error } = await supabase
    .from('assessment_shares')
    .delete()
    .eq('assessment_id', assessmentId)

  if (error) throw error
}

export const getSharedAssessment = async (shareToken) => {
  if (!supabase) {
    throw new Error('Supabase ist nicht konfiguriert.')
  }

  const { data, error } = await supabase.rpc('get_shared_assessment', {
    p_share_token: shareToken
  })

  if (error) throw mapShareError(error)

  const row = getSingleRow(data)
  return row ? mapSharedAssessment(row) : null
}
