import type { SolveInput, SolveResult } from '~/shared/types/schedule'
import { buildModel } from './modelBuilder'
import { parseAssignments } from './resultParser'
import { checkFeasibility } from './feasibilityCheck'

export async function solveSchedule(input: SolveInput): Promise<SolveResult> {
  const startTime = Date.now()

  // Pre-solve sanity check
  const issues = checkFeasibility(input)
  if (issues.length > 0 && issues.some(i => i.blocking)) {
    return {
      status: 'infeasible',
      assignments: [],
      infeasibility_hints: issues.map(i => ({ description: i.message }))
    }
  }

  try {
    // Dynamic import — HiGHS WASM is large
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const HiGHS = (await import('highs' as any)).default
    const highs = await HiGHS()

    const model = buildModel(input)
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const result = highs.solve(model, {}) as Record<string, unknown>

    const duration_ms = Date.now() - startTime
    const status = result.Status as string

    if (status === 'Infeasible' || status === 'Infeasible or Unbounded') {
      return {
        status: 'infeasible',
        assignments: [],
        duration_ms,
        infeasibility_hints: [
          { description: 'Das Optimierungsproblem hat keine Lösung. Bitte überprüfen Sie Ihre Bedingungen, insbesondere ob genügend Mitarbeiter für alle Schichten verfügbar sind.' },
          ...issues.map(i => ({ description: i.message }))
        ]
      }
    }

    if (status !== 'Optimal' && status !== 'Feasible') {
      return {
        status: 'error',
        assignments: [],
        duration_ms,
        infeasibility_hints: [{ description: `Solver Status: ${status}` }]
      }
    }

    const assignments = parseAssignments(result, input)

    return {
      status: 'solved',
      assignments,
      objective_value: result.ObjectiveValue as number,
      duration_ms,
    }
  } catch (err) {
    console.error('Solver error:', err)
    return {
      status: 'error',
      assignments: [],
      infeasibility_hints: [{ description: String(err) }]
    }
  }
}
