import { TableCombination } from '@backend/domain'
import { TableCombinationRepository, TableRepository } from '@backend/repository'
import { Injectable } from '@nestjs/common'
import { differenceBy } from 'es-toolkit/compat'
import { In } from 'typeorm'
import { Transactional } from 'typeorm-transactional'
import { TableCombinationMapper } from '../mappers'
import { CreateTableCombinationRequest, TableCombinationResponse } from '../types'

@Injectable()
export class TableCombinationService {
	constructor(
		private readonly _tableRepository: TableRepository,
		private readonly _tableCombinationRepository: TableCombinationRepository,
	) {}

	async findAll(): Promise<TableCombinationResponse[]> {
		const combinations = await this._tableCombinationRepository.find({ relations: { tables: true } })
		return combinations.map((combination) => TableCombinationMapper.entityToResponse(combination))
	}

	@Transactional()
	async saveMany(combinations: CreateTableCombinationRequest[]): Promise<void> {
		const existing = await this._tableCombinationRepository.find()
		const updated = combinations.filter((comb) => !!comb.id)

		const deletedIds = differenceBy(existing, updated, 'id').map((comb) => comb.id)
		await this._tableCombinationRepository.softDelete({ id: In(deletedIds) })

		const tables = await this._tableRepository.find()

		for (const _combination of combinations) {
			const combTables = tables.filter((table) => _combination.tableIds.includes(table.id))
			const combination: Partial<TableCombination> = {
				id: _combination.id,
				name: _combination.name,
				tables: combTables,
			}
			await this._tableCombinationRepository.save(combination)
		}
	}
}
