<?php

/**
 * NexoPOS Controller
 *
 * @since  1.0
 **/

namespace App\Http\Controllers\Dashboard;

use App\Crud\TransactionCrud;
use App\Crud\TransactionsHistoryCrud;
use App\Http\Controllers\DashboardController;
use App\Models\Transaction;
use App\Models\TransactionAccount;
use App\Models\TransactionHistory;
use App\Services\DateService;
use App\Services\Options;
use App\Services\TransactionService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\View;

class TransactionController extends DashboardController
{
    public function __construct(
        public TransactionService $transactionService,
        public Options $optionsService,
        protected DateService $dateService
    ) {
        // ...
    }

    public function get( $id = null )
    {
        return $this->transactionService->get( $id );
    }

    public function getTransactionHistory( Transaction $transaction )
    {
        return TransactionsHistoryCrud::table( [
            'title' => sprintf( __( '"%s" Record History' ), $transaction->name ),
            'description' => __( 'Shows all histories generated by the transaction.' ),
            'queryParams' => [
                'transaction_id' => $transaction->id,
            ],
        ] );
    }

    public function saveRule( Request $request )
    {
        return $this->transactionService->saveTransactionRule( $request->input( 'rule' ) );
    }

    public function listTransactions()
    {
        return TransactionCrud::table();
    }

    public function createTransaction()
    {
        if ( ! ns()->canPerformAsynchronousOperations() ) {
            session()->flash( 'infoMessage', __( 'Unable to use Scheduled, Recurring and Entity Transactions as Queues aren\'t configured correctly.' ) );
        }

        if ( ns()->option->get( 'ns_accounting_expenses_accounts' ) === null ) {
            session()->flash( 'infoMessage', __( 'You need to configure the expense accounts before creating a transaction.' ) );

            return redirect()->route( 'ns.dashboard.settings', [ 'settings' => 'accounting' ] );
        }

        return View::make( 'pages.dashboard.transactions.create', [
            'title' => __( 'Create New Transaction' ),
            'description' => __( 'Set direct, scheduled transactions.' ),
        ] );
    }

    public function editTransaction( Transaction $transaction )
    {
        if ( ! ns()->canPerformAsynchronousOperations() ) {
            session()->flash( 'infoMessage', __( 'Unable to use Scheduled, Recurring and Entity Transactions as Queues aren\'t configured correctly.' ) );
        }

        return View::make( 'pages.dashboard.transactions.update', [
            'title' => __( 'Update Transaction' ),
            'transaction' => $transaction,
            'description' => __( 'Set direct, scheduled transactions.' ),
        ] );
    }

    public function getConfigurations( Transaction $transaction )
    {
        return $this->transactionService->getConfigurations( $transaction );
    }

    /**
     * Implement a transaction registration
     *
     * @param Request
     * @return json
     */
    public function post( Request $request ) // <= need to add a validation
    {
        $fields = $request->only( [
            'name',
            'active',
            'account_id',
            'description',
            'media_id',
            'value',
            'recurring',
            'type',
            'group_id',
            'occurrence',
            'occurrence_value',
            'scheduled_date',
        ] );

        return $this->transactionService->create( $fields );
    }

    public function putTransactionAccount( Request $request, TransactionAccount $account )
    {
        $fields = $request->only( [
            'name',
            'operation',
            'description',
            'account',
        ] );

        return $this->transactionService->editTransactionAccount( $account, $fields );
    }

    /**
     * Implement saving an expense
     * should check the recursive hierarchy
     *
     * @param Request
     * @param int expense id
     * @return json
     */
    public function put( Request $request, $id )
    {
        $fields = $request->only( [
            'name',
            'active',
            'category_id',
            'description',
            'media_id',
            'value',
            'recurring',
            'type',
            'group_id',
            'occurrence',
            'occurrence_value',
            'scheduled_date',
        ] );

        return $this->transactionService->edit( $id, $fields );
    }

    public function delete( Transaction $transaction )
    {
        return $this->transactionService->deleteTransaction( $transaction );
    }

    /**
     * get an expense category
     *
     * @param int|null category id
     * @return json
     */
    public function getExpensesCategories( $id = null )
    {
        return $this->transactionService->getTransactionAccountByID( $id );
    }

    /**
     * get all sub accounts
     *
     * @return Collection
     */
    public function getSubAccounts()
    {
        return $this->transactionService->getSubAccounts();
    }

    /**
     * get all actions
     *
     * @return Collection
     */
    public function getActions()
    {
        return $this->transactionService->getActions();
    }

    public function getRules()
    {
        return $this->transactionService->getRules();
    }

    /**
     * delete a specific transaction account
     */
    public function deleteAccount( TransactionAccount $account )
    {
        return $this->transactionService->deleteTransactionAccount( $account );
    }

    /**
     * Create an transaction account.
     *
     * @param Request
     * @return json
     */
    public function postTransactionsAccount( Request $request )
    {
        $fields = $request->only( [
            'name',
            'operation',
            'description',
            'account',
        ] );

        return $this->transactionService->createAccount( $fields );
    }

    /**
     * Get expenses entries under a specific
     * transaction account
     */
    public function getTransactionAccountsHistory( int $id ): array
    {
        return $this->transactionService->getTransactionAccountByID( $id )->transactions;
    }

    public function transactionsHistory()
    {
        return TransactionsHistoryCrud::table();
    }

    public function triggerTransaction( Transaction $transaction )
    {
        return $this->transactionService->triggerTransaction( $transaction );
    }

    public function getTransactionAccountFromCategory( Request $request )
    {
        return $this->transactionService->getTransactionAccountFromCategory( $request->input( 'identifier' ), $request->input( 'exclude' ) );
    }

    public function resetDefaultAccounts( Request $request )
    {
        ns()->restrict( [ 'nexopos.create.transactions-account' ] );

        return $this->transactionService->createDefaultAccounts();
    }

    public function createReflection( TransactionHistory $history )
    {
        return $this->transactionService->reflectTransactionFromRule( $history, null );
    }
}
