<?php

namespace App\Classes\Modules\Exports\Services;

use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
use App\Models\Transaction;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Illuminate\Http\Request;
use Carbon\Carbon;
use App\Classes\Modules\Accounting\Processors\ListShippingPortalTransactions;
use App\Classes\ValueObjects\Constants\ShippingTransactionType;
use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Support\Facades\Log;
use App\Classes\General\Eloquent\ApplyFiltersToQuery;
use App\Models\StatementTransaction;

class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
{
    use Exportable;

    private $request;
    private $counter = 1;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function headings(): array
    {
        $header = [
            'DocNo',
            'DocDate',
            'DebtorCode',
            'Ref',
            'DebtorName',
            'CurrencyCode',
            'ShipInfo',
            'ItemCode',
            'DetailDescription',
            'FurtherDescription',
            'Qty',
            'UnitPrice',
            'AccNo',
            'DeptNo'
        ];
        return $header;
    }

    /**
     * @return \Illuminate\Support\Collection|mixed
     */
    public function query()
    {
        $data = (new ApplyFiltersToQuery())->execute(StatementTransaction::query(), json_decode($this->request->input('filter'), true));
        if ($this->request->has('bankStatementTransactionId')) $data = $data->whereIn('id',json_decode($this->request->input('bankStatementTransactionId'), true));

        return $data;
    }

    /**
     * @param Transaction $transaction
     *
     * @return array
     */
    public function map($transaction): array
    {
        $statementTransactionOwner = $transaction->owners()->whereIn('status', [ApprovalStatus::APPROVED])->first();
        $logArray = [
            'counter' => $this->counter,
            'system' => $statementTransactionOwner->system,
            'StatementTransactionOwner_id' => $statementTransactionOwner->id,
            'transaction_table_id' => $statementTransactionOwner->owner_id,
        ];
        $this->counter += 1;
        $logArray = json_encode($logArray);

        $filePath = storage_path('logs/exports_invoice_transactions.log');
        $errorFilePath = storage_path('logs/exports_invoice_transactions_error.log');
        $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $logArray . PHP_EOL;
        file_put_contents($filePath, $textToAppend, FILE_APPEND);

        if ($statementTransactionOwner->system == 'EXCHANGE') {
            $row = (App()->make($statementTransactionOwner->owner_type))->where('id', $statementTransactionOwner->owner_id)->first();
            $company = $row->type === TransactionType::PAYMENT ? $row->owner->company : $row->owner->owner;

            $booking = $row->owner;

            return [
                '<<New>>',
                $row->updated_at->format('m/d/Y H:m'),
                $company->debtor,
                $row->type === TransactionType::PAYMENT ? $booking->marking : $company->reference,
                '',
                'MYR',
                $row->type === TransactionType::PAYMENT ? $booking->marking : $row->bill_no,
                $row->type === TransactionType::PAYMENT ? '' : 'W1',
                $row->type === TransactionType::PAYMENT ? 'PLEASE REFER TO THE ATTACHED APPENDIX REF ' . $booking->marking : 'CREDIT SALES',
                '',
                1,
                round($row->amount, 2),
                '500-0000',
                'CIEF'
            ];
        } else {
            $row = (App()->make(ListShippingPortalTransactions::class))->execute([
                'id' => $statementTransactionOwner->owner_id,
                'with_company' => true,
            ]);

            if (empty($row) || $row[0]['status'] != 'success') {
                $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Fetch Shipping Transaction Fail ' . json_encode([
                    'id' => $statementTransactionOwner->owner_id,
                    'with_company' => true,
                    'StatementTransactionOwner_id' => $statementTransactionOwner->id,
                ]) . PHP_EOL;
                file_put_contents($errorFilePath, $textToAppend, FILE_APPEND);

                $textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Shipping Portal Respnose ' . json_encode($row) . PHP_EOL;
                file_put_contents($errorFilePath, $textToAppend, FILE_APPEND);

                Log::info('Error in Exports Invoice Transactions ' . $this->counter);

                return [];
            }

            $row = $row[0];

            return [
                '<<New>>',
                Carbon::parse($row['updated_at'])->format('m/d/Y H:m'),
                $row['debtor_code'],
                $row['type'] === ShippingTransactionType::PAYMENT ? $row['order_reference'] : $row['marking'],
                '',
                'MYR',
                $row['type'] === ShippingTransactionType::PAYMENT ? $row['order_reference'] : $row['bill_no'],
                $row['type'] === ShippingTransactionType::PAYMENT ? '' : 'W1',
                $row['type'] === ShippingTransactionType::PAYMENT ? 'PLEASE REFER TO THE ATTACHED APPENDIX REF `' . $row['order_reference'] : 'CREDIT SALES',
                '',
                1,
                round($row['amount'], 2),
                '500-0000',
                'CIEF'
            ];
        }
    }
}
