<?php

namespace App\Classes\Modules\Accounting\ControllersLogic;


use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Jobs\CreateBankStatementTransactionOwners;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Models\AccountStatement;
use App\Models\StatementAccount;
use App\Models\StatementTransaction;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Maatwebsite\Excel\Facades\Excel;

class ImportBankStatementLogic extends AbstractControllerLogic
{

    /**
     * @return array
     */
    protected function notification():array {
        return [
            'title' => 'Import Bank Statement Transactions Details',
            'message' => 'You have successfully updated the Bank Statement Transactions Details'
        ];
    }


    /**
     * @param Request $request
     * @return JsonResponse
     * @throws MalformedRequestException
     */
    public function logic(Request $request) : JsonResponse
    {

        $files = $request->file('files');

        $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
        foreach ($object->getFiles() as $file){
            $collection = Excel::toCollection(null, json_decode($file)->file_info->original->file, null, null, true);

            $sheet = $collection->first()->skip(1);

            $statementDetails = $sheet->first();

            $accountNumber = $statementDetails[0];
            $accountType = $statementDetails[1];
            $accountName = $statementDetails[2];
            $accountCurrency = $statementDetails[3];
            $dateFrom = carbon::parse(str_replace(' MY (UTC+08:00)', '', $statementDetails[4]));
            $dateTo = carbon::parse(str_replace(' MY (UTC+08:00)', '', $statementDetails[5]));
            $totalDebit = $statementDetails[6];
            $totalCredit = $statementDetails[7];
            $beginBalance = $statementDetails[8];
            $endBalance = $statementDetails[9];
            $account = StatementAccount::updateOrCreate(
                ['number' => $accountNumber],
                [
                    'type' => $accountType,
                    'name' => $accountName,
                    'currency' => $accountCurrency,
                ]
            );

            $statement = AccountStatement::where('date_from', $dateFrom)
                ->where('date_to', $dateTo)
                ->where('total_amount', $totalDebit ?: $totalCredit,)
                ->where('begin_balance', $beginBalance)
                ->where('end_balance', $endBalance)->first();


            if(!$statement){
                $statement = new AccountStatement([
                    'date_from' => $dateFrom,
                    'date_to' => $dateTo,
                    'total_amount' => $totalDebit ?: $totalCredit,
                    'begin_balance' => $beginBalance,
                    'end_balance' => $endBalance,
                ]);
            }

            $account->statements()->save($statement);

//            CreateBankStatementTransactionOwners::dispatch($statement);


            $sheet->map(function ($row) use ($statement, $account) {
                $transactionRef = $row[15];
                $amount = $row[17] !== '-' ? ((float) str_replace(',', '', $row[17])) : (-((float) str_replace(',', '', $row[16])));
                $transactionDate = $row[10] !== '-' ? carbon::parse(str_replace(' MY (UTC+08:00)', '', $row[10]) . $row[11]) : null;
                $postingDate = carbon::createFromFormat('d/M/Y H:i', str_replace(' MY (UTC+08:00)', '', $row[12]) . str_replace(' MY (UTC+08:00)', '', $row[13]));
                $transactionDescription = is_numeric($row[14]) ? (int) sprintf('%.2f', $row[14]) : $row[14];
                $tellerId = $row[19];
                $branchChannel = $row[20];
                $transactionCode = $row[21];
                $endBalance = ((float) str_replace(',', '', $row[22]));
                $description2 = $row[25];
                $description3 = $row[26];
                $description4 = $row[27];
                $description5 = $row[28];
                $transaction = new StatementTransaction([
                    'transaction_ref' => $transactionRef,
                    'amount' => $amount,
                    'transaction_date' => $transactionDate,
                    'posting_date' => $postingDate,
                    'transaction_description' => $transactionDescription,
                    'teller_id' => $tellerId,
                    'branch_channel' => $branchChannel,
                    'transaction_code' => $transactionCode,
                    'end_balance' => $endBalance,
                    'transaction_description_2' => $description2,
                    'transaction_description_3' => $description3,
                    'transaction_description_4' => $description4,
                    'transaction_description_5' => $description5,
                ]);

                // Check if the transaction already exists for this statement
                $existingTransaction = StatementTransaction::where('transaction_ref', $transactionRef)
                    ->where('posting_date', $postingDate)
                    ->where('amount', $amount)
                    // ->where('transaction_description', $transactionDescription)      //commented this line because same transaction have different transaction description
                    ->where('teller_id', $tellerId)
                    ->where('branch_channel', $branchChannel)
                    ->where('transaction_code', $transactionCode)
                    ->whereRaw("CAST(REPLACE(end_balance,',','') AS DECIMAL(15,2)) = ?",[$endBalance])
                    ->first();

                if (!$existingTransaction) {
                    $statement->transactions()->save($transaction);
                }

                return $transaction;
            });
        }



        return $this->response([]);

    }

}
