<?php

namespace App\Http\Controllers\Imports;

use App\Classes\Modules\Imports\Services\ImportsBankRecord;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Group;
use App\Models\Transaction;
use App\Models\Wallet;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use PhpOffice\PhpSpreadsheet\Shared\Date;

class ImportBankRecordController
{
    /**
     * @param Request $request
     * @return array
     */
    public function import(Request $request) {
        $headers = [
            'Date',
            'Bank',
            'Description',
            'Credit',
            'Debit',
            'Pay For',
            'System Reference',
            'Human Reference',
            'Multiple',
            'Match?',
            'System Amount'
        ];

        $branches = [
            0 => 'MBB Cyber',
            1 => 'MBB SS2',
        ];

        $yes = 'Yes';
        $no = 'No';

        $table = '<table><tr><th>'.implode('</th><th>', $headers).'</th></tr>';

        $collection = Excel::toCollection(new ImportsBankRecord(), 'daily_transaction_nov.xlsx');

        foreach ($collection as $key => $sheet){
            $branch = $branches[$key];
            foreach ($sheet as $row) {
                $date = Carbon::instance(Date::excelToDateTimeObject($row['date']));
                $description = $row['description'];
                $credit = (float) $row['credit'];
                $debit = (float) $row['debit'];
                $creditTransactions = [];
                $debitTransactions = [];

                $systemReference = null;
                $systemAmount = null;

                if($credit){
                    $creditTransactions = $this->getTransactions($date, $credit, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
                    foreach ($creditTransactions as $transaction) {
                        $systemReference[] = $transaction->owner instanceof Booking ? $transaction->owner->marking : $transaction->bill_no;
                        $systemAmount[] = $transaction->amount;
                    }

                    $creditTransactions = $this->getTransactions($date, $credit, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
                    foreach ($creditTransactions as $transaction) {
                        $systemReference[] = $transaction->owner instanceof Booking ? $transaction->owner->marking : $transaction->bill_no;
                        $systemAmount[] = $transaction->amount;
                    }
                }

                if($debit){
                    $debitTransactions = $this->getTransactions($date, $debit, null, null, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], Group::class);

                    if(!count($debitTransactions)) {
                        foreach (['YSN', 'HCK', 'ATVANTIC', 'HIGH HILL'] as $reference){
                            if(str_contains($description, $reference)) {
                                $paymentDate =  $date->addDays(1)->format('Y-m-d');
                                if($reference = 'ATVANTIC'){
                                    $paymentDate =  $date->format('Y-m-d');
                                }
                                $issuer = Company::where('name', 'like', '%'.$reference.'%')->get()->pluck('id');
                                $debitTransactions = Group::whereIn('issuer', $issuer)->whereDate('created_at', $paymentDate)->get();
                                break;
                            }
                        }

                    }

                    foreach ($debitTransactions as $transaction) {
                        $systemReference[] = $transaction->reference;
                        $systemAmount[] = $transaction->amount;
                    }
                }


                $multiple = count($creditTransactions) + count($debitTransactions) > 1 ? $yes : $no;





                $systemReference = $systemReference ? implode(',', $systemReference) : null;
                $systemAmount = $systemAmount ? implode(',', $systemAmount) : null;

                $matches = $systemReference == $row['remarkreferences'] ? $yes : $no;

                $table .= '<tr>
                <td>'.$date->format('d-m-Y').'</td>
                <td>'.$branch.'</td>
                <td>'.$description.'</td>
                <td>'.$credit.'</td>
                <td>'.$debit.'</td>
                <td>'.$row['pay_for'].'</td>
                <td>'.$systemReference.'</td>
                <td>'.$row['remarkreferences'].'</td>
                <td>'.$multiple.'</td>
                <td>'.$matches.'</td>
                <td>'.$systemAmount.'</td>
            </tr>';
            }
        }

        $table .= '</table>';

        echo $table;
    }

    private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $model = Transaction::class) {
        $query = $model::whereIn('status', $statuses)
            ->where(function ($query) use ($ownerType, $paymentMethod, $type) {
                if ($ownerType) {
                    $query->where('owner_type', $ownerType);
                }

                if ($paymentMethod) {
                    $query->where('payment_method', '!=', $paymentMethod);
                }

                if ($type) {
                    $query->where('type', $type);
                }
            })
            ->whereDate('created_at', $date->format('Y-m-d'))
            ->where('amount', '>', ($amount - 0.01))
            ->where('amount', '<', ($amount + 0.01));

        return $query->get();
    }
}
