import { BaseController, CapabilityName, ErrorCodes, ForbiddenError, LoggerPort } from '@humand-packages/common';
import { NextFunction, Request } from 'express';
import { OK } from 'http-status-codes';
import { DeprecatedHumandResponse } from 'humand-packages/monolith/src/api/types/locals';
import { Service } from 'typedi';
import { PermissionsService } from '../../../../permissions/business/services/permissionsService';
import TimeTrackingKioskUserService from '../../../business/services/timeTracking/timeTrackingKioskUser';
import { KioskUserListPaginatedSerializer } from '../../serializationClasses/kioskListPaginatedSerializer';
import { UserProfilePictureListPaginatedSerializer } from '../../serializationClasses/userProfilePictureListPaginatedSerializer';
import { KioskUsersSnapshotVC } from '../../validationClasses/timeTracking/kioskUsersSnapshotVC';
import { ListKioskUsersVC } from '../../validationClasses/timeTracking/listKioskUsers';
import { ListKioskUsersProfilePictureVC } from '../../validationClasses/timeTracking/listKioskUsersProfilePicture';

@Service()
export class TimeTrackingKioskUserController extends BaseController {
    constructor(
        private readonly permissionService: PermissionsService,
        private readonly timeTrackingKioskUserService: TimeTrackingKioskUserService,
        logger: LoggerPort,
    ) {
        super(logger);
    }

    public createSnapshot = async (_req: Request, res: DeprecatedHumandResponse, next: NextFunction): Promise<void> => {
        const { loggedUser } = res.locals;
        const params = res.locals.bodyParams as KioskUsersSnapshotVC;
        await this.endpointHandlerWithGenerics(next, async () => {
            this.permissionService.validateDevOps(loggedUser);
            const result = await this.timeTrackingKioskUserService.createSnapshot(params.instanceIds);
            res.status(OK).json(result);
        });
    };

    public listUsers = async (_req: Request, res: DeprecatedHumandResponse, next: NextFunction): Promise<void> => {
        const { instanceOfLoggedBotApp, loggedBotApp, requiredLimitOffsetPagination } = res.locals;
        if (!loggedBotApp || !instanceOfLoggedBotApp)
            throw new ForbiddenError('The provided bot app has no access to this resource', ErrorCodes.ACCESS_DENIED);
        const params = res.locals.queryParams as ListKioskUsersVC;
        await this.endpointHandlerWithGenerics(next, async () => {
            this.permissionService.validateAnyBotAppCapability(loggedBotApp, [CapabilityName.VIEW_TIME_TRACKING]);
            const { count, lastUpdatedAt, rows } = await this.timeTrackingKioskUserService.listUsers(
                loggedBotApp.id,
                instanceOfLoggedBotApp.getId(),
                params.since,
                requiredLimitOffsetPagination,
            );
            const paginatedResult = new KioskUserListPaginatedSerializer().serializePaginatedList(
                rows,
                requiredLimitOffsetPagination.limit,
                requiredLimitOffsetPagination.offset,
                count,
            );
            res.status(OK).json({ ...paginatedResult, lastUpdatedAt });
        });
    };

    public listUsersProfilePicture = async (_req: Request, res: DeprecatedHumandResponse, next: NextFunction): Promise<void> => {
        const { instanceOfLoggedBotApp, loggedBotApp, requiredLimitOffsetPagination } = res.locals;
        if (!loggedBotApp || !instanceOfLoggedBotApp)
            throw new ForbiddenError('The provided bot app has no access to this resource', ErrorCodes.ACCESS_DENIED);
        const params = res.locals.queryParams as ListKioskUsersProfilePictureVC;
        await this.endpointHandlerWithGenerics(next, async () => {
            this.permissionService.validateAnyBotAppCapability(loggedBotApp, [CapabilityName.VIEW_TIME_TRACKING]);
            const profilePictures = await this.timeTrackingKioskUserService.listUsersProfilePicture(
                instanceOfLoggedBotApp.getId(),
                params.userIds,
                requiredLimitOffsetPagination,
            );
            const paginatedResult = new UserProfilePictureListPaginatedSerializer().serializePaginatedList(
                profilePictures.rows,
                requiredLimitOffsetPagination.limit,
                requiredLimitOffsetPagination.offset,
                profilePictures.count,
            );
            res.status(OK).json(paginatedResult);
        });
    };
}
