import { RRule, RRuleSet, WeekdayStr, Weekday } from 'rrule';
import { DateTime, Duration } from 'luxon';
import { ServerDao } from "../dao/server.dao";
import { AppError } from "../../utils/errors";
import { toUpper } from 'lodash';
import Moment from "moment-timezone";
import { CampaignService } from "../services/campaign.service";
import { PaymentService } from "../services/payment.service";
const validDays: WeekdayKey[] = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];
export class ServerService {
    private accountId: number | null;
    private userId: number | null;
    private language: string;
    private scope: string[] | null;
    private config: userConfig | null;
    private serverDao: ServerDao;
    private campaignService: CampaignService;
    private paymentStreamService: PaymentService;
    constructor(
        private options: {
            language: string;
            scope: string[] | null;
            accountId: number | null;
            userId: number | null;
            config: userConfig | null;
        } = {
                language: process.env.DEFAULT_LANGUAGE_CODE!,
                scope: null,
                config: null,
                userId: null,
                accountId: null,
            }
    ) {
        this.language = options.language;
        this.scope = options.scope ?? [];
        this.config = options.config ?? null;
        this.userId = options.userId ?? null;
        this.accountId = options.accountId ?? null;
        this.serverDao = new ServerDao({
            userId: this.userId,
            accountId: this.accountId,
            language: this.language,
            scope: this.scope,
            config: this.config
        });
        this.campaignService = new CampaignService({
            userId: this.userId,
            accountId: this.accountId,
            language: this.language,
            scope: this.scope,
            config: this.config
        });
        this.paymentStreamService = new PaymentService({
            userId: this.userId,
            accountId: this.accountId,
            language: this.language,
            scope: this.scope,
            config: this.config
        });
    }

    executeCron = async (jobName: string) => {
        try {
            switch (jobName) {
                case 'prepare_campaign':
                    this.campaignService.prepareCampaign();
                    break;
                case 'schedule_campaign':
                    this.campaignService.scheduleCampaign();
                    break;
                case 'send_campaign':
                    this.campaignService.sendCampaign();
                    break;
                case 'assign_user_campaign':
                    this.campaignService.assignUserCampaign();
                    break;
                case 'reset_campaign':
                    this.campaignService.resetCampaign();
                    break;
                case 'update_ended_subscription':
                    this.paymentStreamService.updateEndedSubscriptions({});
                    break;
                default:
                    break;
            }
            return;
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_WITH_DAO', err);
        }
    }

    joinRoom = async (payload: JoinRoomRequest): Promise<null> => {
        try {
            await this.serverDao.joinRoom(payload);
            return null;
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_WITH_DAO', err);
        }
    }

    disconnect = async (payload: DisconnectRequest): Promise<number> => {
        try {
            let status = await this.serverDao.disconnectUser(payload);
            return status;
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_WITH_DAO', err);
        }
    }

    userActive = async (payload: UserActiveRequest): Promise<null> => {
        try {
            await this.serverDao.userActive(payload);
            return null;
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_WITH_DAO', err);
        }
    }

    userAway = async (payload: UserAwayRequest): Promise<null> => {
        try {
            await this.serverDao.userAway(payload);
            return null;
        } catch (err) {
            if (err instanceof AppError) { throw err; }
            throw new AppError(500, 'SOMETHING_WENT_WRONG_WITH_DAO', err);
        }
    }

}
