// form/nc/nc-work-center/nc-work-center-util.js

export function workInProgress(rec) {
	return (
		rec.current.person_state !== 'ready' ||
		(rec.current.started_amount > 0 &&
			(rec.current.produced_amount === 0 || rec.current.produced_amount === '') &&
			(rec.current.failed_amount === 0 || rec.current.failed_amount === ''))
	)
}

// Helper function to find person's previous work entry
let onBreakIdx // Break state constant for continue logic - will be initialized after rec is available
export function previousPersonWork(rec) {
	if (!rec.current?.calc?.started_person_array) {
		return null
	}
	return rec.current.calc.started_person_array.find(item => item.person_id === rec.person && item.started_amount > 0 && onBreakIdx[item.active_state])
}

// Helper functions for work status checks
export function hasWorkInProgress(rec) {
	return rec.current.started_amount > 0 && rec.current.produced_amount === 0 && rec.current.failed_amount === 0
}

export function hasIncompleteWork(rec) {
	return rec.current.started_amount > rec.current.produced_amount + rec.current.failed_amount
}

export function canStartWork(rec) {
	return rec.current.person_state === 'ready' && !hasWorkInProgress(rec) && !hasIncompleteWork(rec) && rec.current.calc.can_start_amount > 0
}

export function canStartAmount(state) {
	// Set start amount error if needed (preserved from original logic)
	const rec = state.rec
	if (rec.person_in_production && rec.current.calc.can_start_amount < 0 && rec.current.started_amount > 0) {
		const tpl = state.hdr.work_center.start_amount_error
		rec.warning_message = tpl.replace('{started}', rec.current.started_amount).replace('{can_start}', rec.current.started_amount + rec.current.calc.can_start_amount)
	} else {
		rec.warning_message = ''
	}
}

export function updateCurrentAndPersonFunction(state, nc, dt, message) {
	const rec = state.rec
	// const hdr = state.hdr
	const arr = state.arr
	const recData = nc.recData
	const recDataSet = nc.recDataSet
	const personSerieIdx = { [rec.constant.product_work_serie.person]: true, [rec.constant.product_work_serie.person_machine]: true }
	onBreakIdx = {
		[rec.constant.active_state.on_break]: true,
		[rec.constant.active_state.continue_on_break]: true
	}
	const allowedStates = nc.invertTable(rec.constant.phase_state)
	function setDefaultToCurrent(rowRec) {
		let value
		for (const key of rec.current_field_set) {
			value = rowRec && recData(rowRec, key)
			if (value == null) {
				value = rec.current_field_set_default[key]
			}
			if (value != null) {
				if (typeof rec.current_field_set_default[key] === 'number') {
					recDataSet(rec.current, key, Number(value))
				} else {
					recDataSet(rec.current, key, value)
				}
			} else {
				// Clear the field if it doesn't exist in the new row
				value = recData(rec.current, key)
				if (value) {
					if (nc.isArray(value)) {
						recDataSet(rec.current, key, [])
					} else if (nc.isObject(value)) {
						recDataSet(rec.current, key, {})
					}
				}
			}
		}
	}
	function setPersonStateToCurrent(workPhaseRec) {
		let value
		for (const key of Object.keys(rec.person_state_field)) {
			value = workPhaseRec[key]
			if (value == null) {
				value = rec.person_state_field[key]
			}
			recDataSet(rec.current, key, value)
		}
		rec.current.person_state = workPhaseRec.work_phase_state
	}
	function setField(infoField, infoRec) {
		let prevConcatValue = ''
		rec.current.calc[infoField] = ''
		let val
		for (const key of rec[infoField + '_field']) {
			val = infoRec && recData(infoRec, key)
			if (val == null)
				if (key === '[you_started]') {
					val = rec.current.started_amount
				} else if (key === '[other_started]') {
					val = (infoRec.calc?.started_amount || 0) - rec.current.started_amount
				}
			if (val != null) {
				if (val !== '') {
					if (rec.field_format[key]) {
						val = dt.formatDate(val, rec.field_format[key])
					}
					// val = String(val)
					rec.current.calc[infoField] += prevConcatValue + val // .substring(0, 100)
				}
			} else {
				prevConcatValue = key
			}
		}
		rec.info = rec.current.calc.work_info + rec.current.calc.time_info + rec.current.calc.amount_info + rec.current.calc.done_info
	}
	function fixPerson() {
		if ((arr.person.length != 1 || arr.person[0].value != '') && nc.recordArrayIndex(arr.person, 'value', rec.person) < 0) {
			rec.person = ''
		}
	}
	return function updateCurrentAndPerson(fromRec, workPhaseRec) {
		// Initialize calc object if it doesn't exist
		if (rec.focus_field === 'started_amount') {
			return
		}
		if (!rec.current.calc) {
			rec.current.calc = {
				can_start_amount: 0,
				started_amount: 0,
				produced_amount: 0,
				failed_amount: 0,
				done_amount: 0
			}
		}
		fixPerson()
		const personWorkPhase = state.grid.work_phase_actual_open?.data?.filter(item => item.person_id === rec.person) || []
		const personOpenWorkPhase = personWorkPhase.filter(item => dt.isZeroDate(item.end_time))
		const unproductiveWorkPhase = personOpenWorkPhase.filter(
			item => item.production_order_id === rec.constant.unproductive_id && item.work_phase_state !== rec.constant.unproductive_work_change_state
		)
		if (unproductiveWorkPhase.length > 1) {
			message.setWarning(state, 'more than one unproductive work phase was found')
		}
		rec.current.enterable = !!rec.person // to boolean
		// Store unproductive work phase data for reuse in other functions
		rec.current.unproductive_state = unproductiveWorkPhase.length > 0 ? unproductiveWorkPhase[0].work_phase_state : 'back'
		// When person is in unproductive state, show all their work phases
		const unfinishedWorkPhase = personOpenWorkPhase.filter(item => item.production_order_id !== rec.constant.unproductive_id)
		rec.error_message = ''
		if (unfinishedWorkPhase.length > 0 && !rec.person_in_production) {
			// Check if all unfinished work phases are in allowed states (edit, ready, stop)
			const startedPhase = unfinishedWorkPhase
				.filter(phase => phase.serie === 'person' && !rec.constant.person_event_stopped[phase.work_phase_state])
				.map(phase => `${phase.production_order_id}.${phase.work_phase_number}, ${phase.resource_id}, '${phase.work_phase_state}'`)
			if (startedPhase.length > 0) {
				rec.error_message = `Cannot exit - you have ${
					startedPhase.length
				} unfinished work phase(s) that are not in ready or stop state. Please finish your work before leaving: ${startedPhase.join(' | ')}`
			}
		} else {
			// Check if person is in unproductive state (excluding 'back' state) and prevent starting work
			if (rec.current.unproductive_state && rec.current.unproductive_state !== rec.constant.unproductive_work_change_state && rec.person_in_production) {
				rec.error_message = `Cannot start work while in '${rec.current.unproductive_state}' state. Please go to ready state first.`
			}
		}
		rec.machine_stop_type_idx = nc.recordArrayIndex(arr.machine_stop_type, 'value', rec.machine_stop_type)
		// Clear machine running warning if machine is stopped
		if (rec.warning_message && rec.warning_message.includes('Cannot exit while machine is running') && (!rec.current.machine_state || rec.current.machine_state === 'stop')) {
			rec.warning_message = ''
		}
		if (rec.selected_work_row <= 0) {
			setDefaultToCurrent()
			// Preserve user input for started_amount when focus is on that field
			rec.current.started_amount = 0
			rec.current.info = ''
			rec.current.prev_started_amount = rec.current.started_amount
			rec.current.enterable = false
			return
		}
		rec.current.prev_started_amount = rec.current.started_amount
		let rowRec = fromRec || state.grid.work.data[rec.selected_work_row - 1] // nc.grid.activatedRow(state, 'work')
		const machineWorkPhase =
			rowRec &&
			personOpenWorkPhase.find(
				item =>
					item.production_order_id === rowRec.production_order_id &&
					item.work_phase_number === rowRec.work_phase_number &&
					(item.serie === 'machine' || item.serie === 'person-machine')
			)
		if (machineWorkPhase) {
			rec.current.machine_state = machineWorkPhase.work_phase_state
			rec.machine_stop_type = arr.machine_stop_type[0]?.value
		} else {
			rec.current.machine_state = ''
			rec.machine_stop_type = arr.machine_stop_type[0]?.value
		}
		if (workPhaseRec == null && rowRec) {
			workPhaseRec = personOpenWorkPhase.find(
				item => item.production_order_id === rowRec.production_order_id && item.work_phase_number === rowRec.work_phase_number && personSerieIdx[item.serie]
			)
			if (!workPhaseRec && unproductiveWorkPhase.length >= 1) {
				workPhaseRec = personWorkPhase.find(
					item => item.production_order_id === rowRec.production_order_id && item.work_phase_number === rowRec.work_phase_number && personSerieIdx[item.serie]
				)
			}
		}
		if (!workPhaseRec || (!rec.person_in_production && !dt.isZeroDate(workPhaseRec.end_time))) {
			// If person is in unproductive button group, only allow open work phases or use unproductive phase
			workPhaseRec = unproductiveWorkPhase[0] || {}
			// Preserve user input for started_amount when focus is on that field
			// Don't reset started_amount if user is actively editing it
			rec.current.started_amount = 0
			rec.current.produced_amount = 0
			rec.current.failed_amount = 0
			rec.current.info = ''
		}
		if (!workPhaseRec?.work_phase_state) {
			workPhaseRec.work_phase_state = 'ready'
		}
		setPersonStateToCurrent(workPhaseRec)
		if (!allowedStates[workPhaseRec.work_phase_state]) {
			if (!rec.constant.unproductive_event_state[workPhaseRec.work_phase_state]) {
				message.setError(state, `unknown person state '${workPhaseRec.work_phase_state}-${rec.current.person_state}'`)
			}
		}
		if (workPhaseRec.production_order_id === rec.constant.unproductive_id) {
			// For unproductive production orders, use the work_phase_state (e.g. 'break', 'eating') as the person_state.
			rec.person_state_icon =
				arr.person_state_unproductive.find(item => item.value === workPhaseRec.work_phase_state)?.icon ||
				arr.unproductive_button_group.find(item => item.value === workPhaseRec.work_phase_state)?.icon
		}
		setDefaultToCurrent(rowRec)
		if (rowRec) {
			setField('time_info', rowRec)
			setField('amount_info', rowRec)
			setField('work_info', rowRec)
			setField('done_info', rowRec)
		}
		arr.machine = arr.resource?.filter(item => item.value === rec.current.resource_id) || []
		rec.machine = rec.current.resource_id
		rec.current.separate_machine_run = rec.keep_running_load_group[rec.machine] || 0 // || 0 -fallback is needed here
		if (rec.current.separate_machine_run < 1) {
			rec.separate_machine_run = 0
		} else if (rec.current.machine_state !== '' && rec.current.machine_state !== 'stop') {
			rec.separate_machine_run = 1
		}
		rec.current.virtual = rec.current.production_order_id.startsWith(rec.constant.virtual_production_order_prefix)
		rec.current.calc.can_start_amount = rowRec?.calc.can_start_amount || 0
		// Set error messages based on work phases
		if (unproductiveWorkPhase.length > 1) {
			message.setWarning(state, 'more than one unproductive work phase was found')
		}
		// Enterable state: what fields can be entered
		if (!rec.person) {
			rec.current.enterable_state = 'none'
		} else if (rec.person && rec.selected_work_row > 0 && rec.current.produced_amount === 0 && rec.current.failed_amount === 0) {
			// Ready state: person selected, work row selected, and no production done yet
			rec.current.enterable_state = 'started'
		} else if (hasWorkInProgress(rec) || hasIncompleteWork(rec)) {
			rec.current.enterable_state = 'produced_failed' // Can enter produced/failed amounts when in active work states (working, setup, material, pause)
		} else {
			rec.current.enterable_state = 'none'
		}
		// Show Stop/Continue button logic
		const canContinue = rec.current.started_amount === 0 && previousPersonWork(rec)
		const hasWorkSelected = state.grid.work.data[rec.selected_work_row - 1]
		rec.current.show_stop_continue = !!(
			rec.person_in_production &&
			hasWorkSelected &&
			(canContinue || (rec.current.enterable_state !== 'none' && rec.current.calc.can_start_amount > 0 && rec.current.started_amount === 0))
		)
		canStartAmount(state)
	}
}
