import type { EventSubChannelRedemptionAddEvent } from "@twurple/eventsub-base";
import type User from "user";

export type pointRedeemOptions = {
	name: string;
	title: string;
	prompt?: string;
	cost: number;
	color?: string;
	sfxredeem?: boolean;
	input?: boolean;
	execution: (
		message: EventSubChannelRedemptionAddEvent,
		sender: User,
	) => Promise<void>;
};

/** The Command class represents a command */
export default class PointRedeem {
	public readonly name: string;
	public readonly title: string;
	public readonly prompt?: string;
	public readonly cost: number;
	public readonly color?: string;
	public readonly sfxredeem?: boolean;
	public readonly input?: boolean;
	public readonly execute: (
		message: EventSubChannelRedemptionAddEvent,
		sender: User,
	) => Promise<void>;
	constructor(options: pointRedeemOptions) {
		this.name = options.name.toLowerCase();
		this.title = options.title;
		this.prompt = options.prompt;
		this.cost = options.cost;
		this.color = options.color;
		this.execute = options.execution;
		this.sfxredeem = options.sfxredeem;
		this.input = options.input;
	}
}

import { readdir } from "node:fs/promises";

/** A map of all (including inactive) redeems mapped to names */
const namedRedeems = new Map<string, PointRedeem>();

const sfxRedeems = new Map<string, PointRedeem>();

const files = await readdir(import.meta.dir);
for (const file of files) {
	if (!file.endsWith(".ts")) continue;
	if (file === import.meta.file) continue;
	const redeem: PointRedeem = await import(
		`${import.meta.dir}/${file.slice(0, -3)}`
	).then((a) => a.default);
	namedRedeems.set(redeem.name, redeem);
	if (redeem.sfxredeem) sfxRedeems.set(redeem.name, redeem);
}

export { namedRedeems, sfxRedeems };

const activeRedeems = new Map<string, PointRedeem>();

/** Map of redeemname to twitch redeem ID */
const idMap = new Map<string, string>();

import { api } from "index";
import logger from "lib/logger";
import { streamerId } from "main";

const currentRedeems = new Map<string, string>();
await api.channelPoints
	.getCustomRewards(streamerId)
	.then((a) => a.map((b) => currentRedeems.set(b.title, b.id)));
for (const [_, redeem] of Array.from(namedRedeems)) {
	const selection = currentRedeems.get(redeem.title);
	if (selection) {
		currentRedeems.delete(redeem.title);
		idMap.set(redeem.name, selection);
		activeRedeems.set(selection, redeem);
	} else {
		if (process.env.NODE_ENV !== "production") continue; // If created with dev-app we won't be able to change it with prod app
		const creation = await api.channelPoints.createCustomReward(streamerId, {
			title: redeem.title,
			prompt: redeem.prompt,
			cost: redeem.cost,
			backgroundColor: redeem.color,
			userInputRequired: redeem.input,
		});
		logger.ok(`Created custom point redeem ${redeem.title}`);
		idMap.set(redeem.name, creation.id);
		activeRedeems.set(creation.id, redeem);
	}
}

Array.from(currentRedeems).map(async ([title, redeem]) => {
	if (process.env.NODE_ENV !== "production") return;
	await api.channelPoints.deleteCustomReward(streamerId, redeem);
	logger.ok(`Deleted custom point redeem ${title}`);
});

logger.ok("Successfully synced all custom point redeems");

export async function enableRedeem(redeem: PointRedeem, id: string) {
	if (process.env.NODE_ENV !== "production") return;
	await api.channelPoints.updateCustomReward(streamerId, id, {
		isEnabled: true,
	});
	activeRedeems.set(id, redeem);
	logger.ok(`Enabled the ${redeem.name} point redeem`);
}

export async function disableRedeem(redeem: PointRedeem, id: string) {
	if (process.env.NODE_ENV !== "production") return;
	await api.channelPoints.updateCustomReward(streamerId, id, {
		isEnabled: false,
	});
	activeRedeems.delete(id);
	logger.ok(`Disabled the ${redeem.name} point redeem`);
}

export { activeRedeems, idMap };
