import { Request, Response, NextFunction } from 'express';
import { CreateDeviceUseCase } from '../../application/use-cases/device/create-device.use-case';
import { GetDeviceByIdUseCase } from '../../application/use-cases/device/get-device-by-id.use-case';
import { GetAllDevicesUseCase } from '../../application/use-cases/device/get-all-devices.use-case';
import { UpdateDeviceStatusUseCase } from '../../application/use-cases/device/update-device-status.use-case';
import { UpdateDevicePushTokenUseCase } from '../../application/use-cases/device/update-device-push-token.use-case';
import {
  CreateDeviceInput,
  UpdateDeviceStatusInput,
  UpdateDevicePushTokenInput,
  PaginationInput,
} from '../../application/dto';

export class DeviceController {
  constructor(
    private readonly createDeviceUseCase: CreateDeviceUseCase,
    private readonly getDeviceByIdUseCase: GetDeviceByIdUseCase,
    private readonly getAllDevicesUseCase: GetAllDevicesUseCase,
    private readonly updateDeviceStatusUseCase: UpdateDeviceStatusUseCase,
    private readonly updateDevicePushTokenUseCase: UpdateDevicePushTokenUseCase,
  ) {}

  create = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const device = await this.createDeviceUseCase.execute(req.body as CreateDeviceInput);
      res.status(201).json({ success: true, data: device });
    } catch (error) {
      next(error);
    }
  };

  getById = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const device = await this.getDeviceByIdUseCase.execute(req.params.id as string);
      res.status(200).json({ success: true, data: device });
    } catch (error) {
      next(error);
    }
  };

  getAll = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const devices = await this.getAllDevicesUseCase.execute(req.query as unknown as PaginationInput);
      res.status(200).json({ success: true, data: devices });
    } catch (error) {
      next(error);
    }
  };

  updateStatus = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const device = await this.updateDeviceStatusUseCase.execute(
        req.params.id as string,
        req.body as UpdateDeviceStatusInput,
      );
      res.status(200).json({ success: true, data: device });
    } catch (error) {
      next(error);
    }
  };

  updatePushToken = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const input = req.body as UpdateDevicePushTokenInput;
      console.log('[DeviceController] Updating push token', {
        deviceId: req.params.id,
        pushToken: input.pushToken,
      });
      const device = await this.updateDevicePushTokenUseCase.execute(
        req.params.id as string,
        input,
      );
      res.status(200).json({ success: true, data: device });
    } catch (error) {
      next(error);
    }
  };
}

