import { Body, Controller, Get, Inject, Param, Post, Query, Request, UseGuards } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { FileService } from '../file/file.service.js';
import { OptionalJwtAuthGuard } from '../jwt-auth/optional-jwt-auth.guard.js';
import { User } from '../models/db.model';
import { JwtUser, Subscription, UserListingCriteria } from '../models/main.model.js';
import { UserService } from './user.service.js';

@Controller('user')
export class UserController {
  constructor(
    private userService: UserService,
    private fileService: FileService,
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}
  @UseGuards(OptionalJwtAuthGuard)
  @Get()
  findByMail(@Request() req, @Query('mail') mail: string): any {
    this.logger.info(`Searching for user with EMail: ${mail}`);
    const user = this.userService.getUserByMail(mail, req.user as JwtUser);
    this.logger.info(`Found user: ${JSON.stringify(user)}`);
    return user;
  }

  @Get(':id')
  findById(@Param('id') id: string): any {
    this.logger.info(`Searching for user with ID: ${id}`);
    const user = this.userService.getUserById(id);
    this.logger.info(`Found user: ${JSON.stringify(user)}`);
    return user;
  }
  @Post()
  save(@Body() user: any): Promise<User> {
    this.logger.info(`Saving user: ${JSON.stringify(user)}`);
    const savedUser = this.userService.saveUser(user);
    this.logger.info(`User persisted: ${JSON.stringify(savedUser)}`);
    return savedUser;
  }

  @Post('search')
  find(@Body() criteria: UserListingCriteria): any {
    this.logger.info(`Searching for users with criteria: ${JSON.stringify(criteria)}`);
    const foundUsers = this.userService.searchUserListings(criteria);
    this.logger.info(`Found users: ${JSON.stringify(foundUsers)}`);
    return foundUsers;
  }
  @Post('findTotal')
  findTotal(@Body() criteria: UserListingCriteria): Promise<number> {
    return this.userService.getUserListingsCount(criteria);
  }
  @Get('states/all')
  async getStates(): Promise<any[]> {
    this.logger.info(`Getting all states for users`);
    const result = await this.userService.getStates();
    this.logger.info(`Found ${result.length} entries`);
    return result;
  }

  @Get('subscriptions/:id')
  async findSubscriptionsById(@Param('id') id: string): Promise<Subscription[]> {
    const subscriptions = this.fileService.getSubscriptions();
    const user = await this.userService.getUserById(id);
    subscriptions.forEach(s => {
      s.userId = user.id;
      s.start = user.created;
      s.modified = user.created;
    });
    return subscriptions;
  }
}
