import { Request, Response, NextFunction } from 'express';
import { CreateNetworkUseCase } from '../../application/use-cases/admin/create-network.use-case';
import { CreateTokenUseCase } from '../../application/use-cases/admin/create-token.use-case';
import { UpdateTokenUseCase } from '../../application/use-cases/admin/update-token.use-case';
import { DeleteTokenUseCase } from '../../application/use-cases/admin/delete-token.use-case';
import { UpdateTokenMinimumSwapValueUseCase } from '../../application/use-cases/admin/update-token-minimum-swap-value.use-case';
import { FetchTokenDataUseCase } from '../../application/use-cases/admin/fetch-token-data.use-case';
import {
  CreateNetworkInput,
  CreateTokenInput,
  FetchTokenDataInput,
  UpdateTokenInput,
  UpdateTokenMinimumSwapValueInput,
} from '../../application/dto';

export class AdminController {
  constructor(
    private readonly createNetworkUseCase: CreateNetworkUseCase,
    private readonly createTokenUseCase: CreateTokenUseCase,
    private readonly updateTokenUseCase: UpdateTokenUseCase,
    private readonly deleteTokenUseCase: DeleteTokenUseCase,
    private readonly updateTokenMinimumSwapValueUseCase: UpdateTokenMinimumSwapValueUseCase,
    private readonly fetchTokenDataUseCase: FetchTokenDataUseCase,
  ) {}

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

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

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

  deleteToken = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      await this.deleteTokenUseCase.execute(req.params.id as string);
      res.status(204).send();
    } catch (error) {
      next(error);
    }
  };

  updateTokenMinimumSwapValue = async (
    req: Request,
    res: Response,
    next: NextFunction,
  ): Promise<void> => {
    try {
      const token = await this.updateTokenMinimumSwapValueUseCase.execute({
        tokenId: req.params.id as string,
        minimumSwapValue: (req.body as UpdateTokenMinimumSwapValueInput).minimumSwapValue,
      });
      res.status(200).json({ success: true, data: token });
    } catch (error) {
      next(error);
    }
  };

  fetchTokenData = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const data = await this.fetchTokenDataUseCase.execute(req.body as FetchTokenDataInput);
      res.status(200).json({ success: true, data });
    } catch (error) {
      next(error);
    }
  };
}
