{"version":3,"file":"single-interactions.mjs","sources":["../../../../packages/components/src/subject/single-interactions.ts"],"sourcesContent":["import type { AnswerType } from './types'\nimport { type SearchResult, SubjectError } from './subject-shared'\n\nexport interface SingleSearchDependencies {\n  answerType: AnswerType\n  query: string\n  searchApi?: string\n  searchHandler?: (query: string, answerType: number) => Promise<SearchResult[]>\n  fetcher?: typeof fetch\n}\n\nexport interface SingleSearchSelection {\n  selectedTitle: string\n  detail: SearchResult & {\n    id: string | number\n    customId: string\n  }\n}\n\nexport interface SingleDialogState {\n  correctHintDialogOpen: boolean\n  changeTypeDialogOpen: boolean\n  hasShownCorrectHint: boolean\n}\n\nexport type SingleSaveDecision =\n  | { kind: 'error', error: SubjectError }\n  | { kind: 'confirm-change-type' }\n  | { kind: 'confirm-correct-hint' }\n  | { kind: 'save' }\n\nexport function resolveSingleSearchAnswerType(type: AnswerType) {\n  if (type === 'single') {\n    return 0\n  }\n  if (type === 'multiple') {\n    return 1\n  }\n  return 5\n}\n\nexport function hasSingleSearchSource(searchApi?: string, searchHandler?: SingleSearchDependencies['searchHandler']) {\n  return !!searchApi || typeof searchHandler === 'function'\n}\n\nexport function normalizeSingleSearchResults(payload: any): SearchResult[] {\n  const list = Array.isArray(payload) ? payload : Array.isArray(payload?.data) ? payload.data : []\n  return list.map((item: any) => ({\n    ...item,\n    value: item?.value || item?.title || '',\n  }))\n}\n\nexport function buildSingleSearchUrl(searchApi: string, query: string, answerType: number) {\n  const params = new URLSearchParams({\n    searchKey: query,\n    answerType: String(answerType),\n  })\n  return `${searchApi}${searchApi.includes('?') ? '&' : '?'}${params.toString()}`\n}\n\nexport async function searchSingleSubjects({\n  answerType,\n  query,\n  searchApi,\n  searchHandler,\n  fetcher = fetch,\n}: SingleSearchDependencies): Promise<SearchResult[]> {\n  const normalizedAnswerType = resolveSingleSearchAnswerType(answerType)\n\n  if (typeof searchHandler === 'function') {\n    const result = await searchHandler(query, normalizedAnswerType)\n    return Array.isArray(result) ? result : []\n  }\n\n  if (!searchApi) {\n    return []\n  }\n\n  const response = await fetcher(buildSingleSearchUrl(searchApi, query, normalizedAnswerType))\n  if (!response.ok) {\n    throw new Error(`HTTP ${response.status}`)\n  }\n\n  return normalizeSingleSearchResults(await response.json())\n}\n\nexport function buildSingleSearchSelection(item: SearchResult, customId = ''): SingleSearchSelection {\n  const selectedTitle = item.value || item.title || ''\n\n  return {\n    selectedTitle,\n    detail: {\n      ...item,\n      id: item.id ?? item.examId ?? item.questionId,\n      title: item.title || selectedTitle,\n      value: selectedTitle,\n      customId,\n    },\n  }\n}\n\nexport function resolveSingleSaveDecision({\n  errors,\n  hasShownCorrectHint,\n  shouldShowCorrectHint,\n}: {\n  errors: SubjectError[]\n  hasShownCorrectHint: boolean\n  shouldShowCorrectHint: boolean\n}): SingleSaveDecision {\n  const convertWarning = errors.find(error => error.code === 'SINGLE_MULTI_CORRECT')\n  const blockingError = errors.find(error => error.code !== 'SINGLE_MULTI_CORRECT')\n\n  if (blockingError) {\n    return { kind: 'error', error: blockingError }\n  }\n  if (convertWarning) {\n    return { kind: 'confirm-change-type' }\n  }\n  if (!hasShownCorrectHint && shouldShowCorrectHint) {\n    return { kind: 'confirm-correct-hint' }\n  }\n\n  return { kind: 'save' }\n}\n\nexport function applySingleSaveDecisionToDialogs(\n  state: SingleDialogState,\n  decision: SingleSaveDecision,\n): SingleDialogState {\n  if (decision.kind === 'confirm-change-type') {\n    return {\n      ...state,\n      correctHintDialogOpen: false,\n      changeTypeDialogOpen: true,\n    }\n  }\n\n  if (decision.kind === 'confirm-correct-hint') {\n    return {\n      ...state,\n      correctHintDialogOpen: true,\n      changeTypeDialogOpen: false,\n    }\n  }\n\n  return state\n}\n\nexport function dismissSingleCorrectHintDialog(state: SingleDialogState): SingleDialogState {\n  return {\n    ...state,\n    correctHintDialogOpen: false,\n  }\n}\n\nexport function acknowledgeSingleCorrectHint(state: SingleDialogState): SingleDialogState {\n  return {\n    ...state,\n    correctHintDialogOpen: false,\n    hasShownCorrectHint: true,\n  }\n}\n\nexport function dismissSingleChangeTypeDialog(state: SingleDialogState): SingleDialogState {\n  return {\n    ...state,\n    changeTypeDialogOpen: false,\n  }\n}\n"],"names":["resolveSingleSearchAnswerType","type","hasSingleSearchSource","searchApi","searchHandler","normalizeSingleSearchResults","payload","item","buildSingleSearchUrl","query","answerType","params","searchSingleSubjects","fetcher","normalizedAnswerType","result","response","buildSingleSearchSelection","customId","selectedTitle","resolveSingleSaveDecision","errors","hasShownCorrectHint","shouldShowCorrectHint","convertWarning","error","blockingError","applySingleSaveDecisionToDialogs","state","decision","dismissSingleCorrectHintDialog","acknowledgeSingleCorrectHint","dismissSingleChangeTypeDialog"],"mappings":"AA+BO,SAASA,EAA8BC,EAAkB,CAC9D,OAAIA,IAAS,SACJ,EAELA,IAAS,WACJ,EAEF,CACT,CAEO,SAASC,EAAsBC,EAAoBC,EAA2D,CACnH,MAAO,CAAC,CAACD,GAAa,OAAOC,GAAkB,UACjD,CAEO,SAASC,EAA6BC,EAA8B,CAEzE,OADa,MAAM,QAAQA,CAAO,EAAIA,EAAU,MAAM,QAAQA,GAAS,IAAI,EAAIA,EAAQ,KAAO,CAAA,GAClF,IAAKC,IAAe,CAC9B,GAAGA,EACH,MAAOA,GAAM,OAASA,GAAM,OAAS,EAAA,EACrC,CACJ,CAEO,SAASC,EAAqBL,EAAmBM,EAAeC,EAAoB,CACzF,MAAMC,EAAS,IAAI,gBAAgB,CACjC,UAAWF,EACX,WAAY,OAAOC,CAAU,CAAA,CAC9B,EACD,MAAO,GAAGP,CAAS,GAAGA,EAAU,SAAS,GAAG,EAAI,IAAM,GAAG,GAAGQ,EAAO,SAAA,CAAU,EAC/E,CAEA,eAAsBC,EAAqB,CACzC,WAAAF,EACA,MAAAD,EACA,UAAAN,EACA,cAAAC,EACA,QAAAS,EAAU,KACZ,EAAsD,CACpD,MAAMC,EAAuBd,EAA8BU,CAAU,EAErE,GAAI,OAAON,GAAkB,WAAY,CACvC,MAAMW,EAAS,MAAMX,EAAcK,EAAOK,CAAoB,EAC9D,OAAO,MAAM,QAAQC,CAAM,EAAIA,EAAS,CAAA,CAC1C,CAEA,GAAI,CAACZ,EACH,MAAO,CAAA,EAGT,MAAMa,EAAW,MAAMH,EAAQL,EAAqBL,EAAWM,EAAOK,CAAoB,CAAC,EAC3F,GAAI,CAACE,EAAS,GACZ,MAAM,IAAI,MAAM,QAAQA,EAAS,MAAM,EAAE,EAG3C,OAAOX,EAA6B,MAAMW,EAAS,MAAM,CAC3D,CAEO,SAASC,EAA2BV,EAAoBW,EAAW,GAA2B,CACnG,MAAMC,EAAgBZ,EAAK,OAASA,EAAK,OAAS,GAElD,MAAO,CACL,cAAAY,EACA,OAAQ,CACN,GAAGZ,EACH,GAAIA,EAAK,IAAMA,EAAK,QAAUA,EAAK,WACnC,MAAOA,EAAK,OAASY,EACrB,MAAOA,EACP,SAAAD,CAAA,CACF,CAEJ,CAEO,SAASE,EAA0B,CACxC,OAAAC,EACA,oBAAAC,EACA,sBAAAC,CACF,EAIuB,CACrB,MAAMC,EAAiBH,EAAO,KAAKI,GAASA,EAAM,OAAS,sBAAsB,EAC3EC,EAAgBL,EAAO,KAAKI,GAASA,EAAM,OAAS,sBAAsB,EAEhF,OAAIC,EACK,CAAE,KAAM,QAAS,MAAOA,CAAA,EAE7BF,EACK,CAAE,KAAM,qBAAA,EAEb,CAACF,GAAuBC,EACnB,CAAE,KAAM,sBAAA,EAGV,CAAE,KAAM,MAAA,CACjB,CAEO,SAASI,EACdC,EACAC,EACmB,CACnB,OAAIA,EAAS,OAAS,sBACb,CACL,GAAGD,EACH,sBAAuB,GACvB,qBAAsB,EAAA,EAItBC,EAAS,OAAS,uBACb,CACL,GAAGD,EACH,sBAAuB,GACvB,qBAAsB,EAAA,EAInBA,CACT,CAEO,SAASE,EAA+BF,EAA6C,CAC1F,MAAO,CACL,GAAGA,EACH,sBAAuB,EAAA,CAE3B,CAEO,SAASG,EAA6BH,EAA6C,CACxF,MAAO,CACL,GAAGA,EACH,sBAAuB,GACvB,oBAAqB,EAAA,CAEzB,CAEO,SAASI,EAA8BJ,EAA6C,CACzF,MAAO,CACL,GAAGA,EACH,qBAAsB,EAAA,CAE1B"}