import { Body, Controller, Post, Route, SuccessResponse, Middlewares } from "tsoa";
import { authenticateMiddleware } from "../../middleware/authentication";
import { ApiValidationError } from "../../Models/Server.Error.model";
import {
    CreateCashFlowParams,
    DeleteMovementParams,
    PaginateCashFlowParams,
    PaginateCashFlowResults,
} from "../../Models/CashFlow/CashFlow.Interface";
import { ApiVoidResult } from "../../Models/Api.VoidResult.type";
import { CashFlowService } from "./CashFlow.Service";
import {
    CalculateCashFlowBalanceParams,
    CashFlowHistoryView,
    FindCashFlowBalanceParams,
    ICashFlowBalance,
} from "../../Models/CashFlowBalance/CashFlowBalance.Interface";

@Route("cashflow/create")
@Middlewares(authenticateMiddleware)
export class CashFlowCreateController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async createCashFlowMovements(
        @Body() requestBody: CreateCashFlowParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CashFlowService().createCashFlowMovements(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Done",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("cashflow/calculate-balance")
@Middlewares(authenticateMiddleware)
export class CashFlowCalculateBalanceController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async calculateBalance(
        @Body() requestBody: CalculateCashFlowBalanceParams
    ): Promise<ICashFlowBalance | ApiValidationError> {
        try {
            const balance = await new CashFlowService().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("cashflow/delete")
@Middlewares(authenticateMiddleware)
export class CashFlowDeleteController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async delete(
        @Body() requestBody: DeleteMovementParams
    ): Promise<ApiVoidResult | ApiValidationError> {
        try {
            await new CashFlowService().delete(requestBody);
            this.setStatus(200);
            return {
                success: true,
                message: "Done",
            };
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("cashflow/history")
@Middlewares(authenticateMiddleware)
export class CashFlowHistoryController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async history(
        @Body() requestBody: FindCashFlowBalanceParams
    ): Promise<CashFlowHistoryView | ApiValidationError> {
        try {
            const balance = await new CashFlowService().history(requestBody);
            this.setStatus(200);
            return balance;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("cashflow/paginate")
@Middlewares(authenticateMiddleware)
export class CashFlowPaginateController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async history(
        @Body() requestBody: PaginateCashFlowParams
    ): Promise<PaginateCashFlowResults | ApiValidationError> {
        try {
            const results = await new CashFlowService().paginate(requestBody);
            this.setStatus(200);
            return results;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}

@Route("cashflow/paginate-balance")
@Middlewares(authenticateMiddleware)
export class CashFlowPaginateBalanceController extends Controller {
    @SuccessResponse(200, "Done")
    @Post()
    public async history(
        @Body() requestBody: FindCashFlowBalanceParams
    ): Promise<number | ApiValidationError> {
        try {
            const balance = await new CashFlowService().getCashFlowBlaance(requestBody);
            this.setStatus(200);
            return balance;
        } catch (e) {
            const errorOccurred: Error = e as Error;
            this.setStatus(500);
            return new ApiValidationError(500, errorOccurred.message);
        }
    }
}
