import { SessionStore } from '@backend/auth'
import { SettingsRepository } from '@backend/repository'
import { BadRequestException, ForbiddenException, Injectable } from '@nestjs/common'
import { SettingsMapper } from '../mappers'
import { SaveSettingsRequest, SettingsResponse } from '../types'

@Injectable()
export class SettingsService {
	constructor(private readonly _settingsRepository: SettingsRepository) {}

	async find(): Promise<SettingsResponse> {
		const settings = await this._settingsRepository.findOneBy({})
		if (!settings) throw new BadRequestException()

		return SettingsMapper.entityToResponse(settings)
	}

	async save(request: SaveSettingsRequest): Promise<void> {
		const tenantId = SessionStore.tenantId
		if (!tenantId) throw new ForbiddenException()

		// The whole row has to be read: the merges below extend the stored blocks with the
		// fields the request carries. A narrowing `select` leaves them undefined, the spread
		// turns into a no-op and the request silently REPLACES the stored block.
		const existing = await this._settingsRepository.findOne({ where: { tenantId } })

		if (!existing) {
			await this._settingsRepository.save(request)
			return
		}

		if (request.customerApp) {
			request.customerApp = { ...existing.customerApp, ...request.customerApp }
		}

		if (request.reservation) {
			request.reservation = { ...existing.reservation, ...request.reservation }
		}

		if (request.restaurant) {
			request.restaurant = { ...existing.restaurant, ...request.restaurant }
		}

		await this._settingsRepository.update({ tenantId }, request)
	}
}
