import { Body, Controller, Post, Route, SuccessResponse, Middlewares } from "tsoa";
import { authenticateMiddleware } from "../../middleware/authentication";
import { ApiValidationError } from "../../Models/Server.Error.model";
import {
    ClientAccountReport,
    ClientAccountView,
    FindClientAccountsParams,
    GetClientAccountReportParams,
    IClientAccount,
} from "../../Models/ClientAccounts/ClientAccounts.Interface";
import { ClientAccountsService } from "./ClientAccounts.Service";
import {
    CalculateClientAccountBalanceParams,
    CreateClientAccountMovementParams,
    IClientAccountMovement,
    PaginateClientAccountMovementsParams,
    PaginateClientAccountMovementsResults,
} from "../../Models/ClientAccountMovements/ClientAccountMovements.Interface";

@Route("client-accounts/find")
@Middlewares(authenticateMiddleware)
export class ClientAccountsController extends Controller {
    @SuccessResponse(200, "Cuenta encontrada exitosamente")
    @Post()
    public async findById(
        @Body() requestBody: FindClientAccountsParams
    ): Promise<IClientAccount | ApiValidationError> {
        try {
            const account = await new ClientAccountsService().findById(requestBody);
            this.setStatus(200);
            return account;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("client-accounts/calculate-balance")
@Middlewares(authenticateMiddleware)
export class ClientAccountsCalculateBalanceController extends Controller {
    @SuccessResponse(200, "Balance calculado exitosamente")
    @Post()
    public async calculateBalance(
        @Body() requestBody: CalculateClientAccountBalanceParams
    ): Promise<number | ApiValidationError> {
        try {
            const balance = await new ClientAccountsService().calculateBalance(requestBody);
            this.setStatus(200);
            return balance;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("client-accounts/add-movement")
@Middlewares(authenticateMiddleware)
export class ClientAccountsAddMovementController extends Controller {
    @SuccessResponse(200, "Movimiento agregado exitosamente")
    @Post()
    public async addMovement(
        @Body() requestBody: CreateClientAccountMovementParams
    ): Promise<IClientAccountMovement | ApiValidationError> {
        try {
            const movement = await new ClientAccountsService().addMovement(requestBody);
            this.setStatus(200);
            return movement;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("client-accounts/paginate-movements")
@Middlewares(authenticateMiddleware)
export class ClientAccountsPaginateMovementsController extends Controller {
    @SuccessResponse(200, "Movimientos paginados exitosamente")
    @Post()
    public async paginateMovements(
        @Body() requestBody: PaginateClientAccountMovementsParams
    ): Promise<PaginateClientAccountMovementsResults | ApiValidationError> {
        try {
            const movements = await new ClientAccountsService().paginateMovements(requestBody);
            this.setStatus(200);
            return movements;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("client-accounts/client-view")
@Middlewares(authenticateMiddleware)
export class ClientAccountsViewController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async clientView(
        @Body() requestBody: FindClientAccountsParams
    ): Promise<ClientAccountView | ApiValidationError> {
        try {
            const view = await new ClientAccountsService().clientAccountView(requestBody);
            this.setStatus(200);
            return view;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("client-accounts/get-account-report")
@Middlewares(authenticateMiddleware)
export class ClientAccountsReportController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async getAccountReport(
        @Body() requestBody: GetClientAccountReportParams
    ): Promise<ClientAccountReport | ApiValidationError> {
        try {
            const view = await new ClientAccountsService().getAccountReport(requestBody);
            this.setStatus(200);
            return view;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
