import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import * as fs from 'fs';
import * as path from 'path';
import { QuickTile, QuickTileDocument } from './quick-tiles.model';
import { defaultQuickTiles } from './quick-tiles.seed';

@Injectable()
export class QuickTilesService implements OnModuleInit {
	private readonly logger = new Logger(QuickTilesService.name);

	constructor(
		@InjectModel(QuickTile.name)
		private readonly quickTileModel: Model<QuickTileDocument>,
	) {}

	async onModuleInit() {
		await this.syncFromConfigFile();
	}

	/**
	 * Reads quick-tiles.config.json on every startup and upserts each tile by tileId.
	 * If the JSON file is missing, falls back to the TS seed (one-time only when collection is empty).
	 *
	 * To edit tiles without an admin GUI:
	 *   1. Edit  backend/src/modules/quick-tiles/quick-tiles.config.json
	 *   2. Restart the backend
	 *
	 * Tiles created via admin API (not in the JSON) are preserved.
	 */
	private async syncFromConfigFile() {
		const configPath = path.join(__dirname, 'quick-tiles.config.json');

		let configTiles: any[] | null = null;
		try {
			if (fs.existsSync(configPath)) {
				configTiles = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
			}
		} catch (err) {
			this.logger.warn(`Failed to read quick-tiles.config.json: ${(err as Error).message}`);
		}

		if (configTiles && configTiles.length) {
			let upserted = 0;
			for (const tile of configTiles) {
				if (!tile.tileId) continue;
				await this.quickTileModel.updateOne(
					{ tileId: tile.tileId },
					{ $set: tile },
					{ upsert: true },
				);
				upserted++;
			}
			this.logger.log(`Synced ${upserted} quick tile(s) from quick-tiles.config.json`);
			return;
		}

		// Fallback: TS seed only on first run
		const count = await this.quickTileModel.estimatedDocumentCount();
		if (count === 0) {
			this.logger.log('No config file and collection empty - seeding from TS defaults');
			await this.quickTileModel.insertMany(defaultQuickTiles);
		}
	}

	async getActiveTiles(): Promise<QuickTile[]> {
		return this.quickTileModel
			.find({ isActive: true })
			.sort({ order: 1 })
			.lean()
			.exec();
	}

	async getAllTiles(): Promise<QuickTile[]> {
		return this.quickTileModel
			.find()
			.sort({ order: 1 })
			.lean()
			.exec();
	}

	async getTileById(tileId: string): Promise<QuickTile | null> {
		return this.quickTileModel.findOne({ tileId }).lean().exec();
	}
}
