<?php

namespace App\Classes\Modules\Imports\Services;

use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Jobs\Commands\V2\ProcessPaymentReportV2CommandJob;
use App\Classes\Jobs\Commands\V2\ProcessSalesInvoiceReportV2CommandJob;
use App\Classes\Jobs\Commands\V2\ProcessCreditNoteReportV2CommandJob;
use App\Classes\Jobs\Commands\V2\ProcessSalesDepositByWalletPaymentEntryV2CommandJob;
use App\Classes\Jobs\Commands\V2\ProcessSalesDepositByWalletRefundEntryV2CommandJob;
use Illuminate\Support\Facades\Log;

class AutoCountDataImport implements ToCollection, WithHeadingRow, WithChunkReading
{
    protected $reportType;

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

    public function headingRow(): int
    {
        return 1;
    }

    /**
     * @param Collection $collection
     */
    public function collection(Collection $collection)
    {
        static $headerProcessed = false;
        foreach ($collection as $row) {
            if (!$headerProcessed) {
                $header = $row->keys()->map(fn($h) => strtolower(trim($h)))->toArray();
                $this->validateHeader($header, $this->reportType);
                $headerProcessed = true;
            }

            if ($this->reportType === 'Sales Invoice Report') {
                ProcessSalesInvoiceReportV2CommandJob::dispatch($row->toArray());
            }
            elseif ($this->reportType === '01R - RECEIVE PAYMENT [AR RECEIVE PAYMENT]') {
                ProcessPaymentReportV2CommandJob::dispatch($row->toArray());
            }
            else if ($this->reportType === 'Credit Note Report') {
                ProcessCreditNoteReportV2CommandJob::dispatch($row->toArray());
            }
            else if ($this->reportType === '01DRW - Sales Deposit by Wallet [AR PAYMENT ENTRY]') {
                ProcessSalesDepositByWalletPaymentEntryV2CommandJob::dispatch($row->toArray());
            }
            else if ($this->reportType === '01DRF - Sales Deposit by Wallet [AR REFUND ENTRY]') {
                ProcessSalesDepositByWalletRefundEntryV2CommandJob::dispatch($row->toArray());
            }
            else {
                throw new MalformedRequestException('Cannot process report type: ' . $this->reportType);
            }
        }
    }

    public function chunkSize(): int
    {
        return 1000;
    }

    private function validateHeader(array $header, String $reportType)
    {
        $optionalColumn = 'einvoicevalidationlink';
        $salesInvoiceHeader = [
            'docno', 'docdate', 'debtorcode', 'ref', 'shipinfo', 'accno',
            'detaildescription', 'furtherdescription', 'classification',
            'deptno', 'qty', 'unitprice', 'submiteinvoice', 'consolidatedeinvoice'
        ];
        $customersReportHeader = [
            'tin', 'identityno', 'name', 'identitytype', 'taxclassification', 'msiccode',
            'businessactivitydesc', 'debtorcode', 'tradename', 'address', 'postcode',
            'phone', 'emailaddress', 'city', 'countrycode', 'statecode'
        ];
        $paymentReportHeader = [
            'docno',
            'docdate',
            'debtorcode',
            'description',
            'paymentmethod',
            'paymentamt',
            'knockoffdocno'
        ];

        $creditNoteReportHeader = [
            'docno',
            'docdate',
            'debtorcode',
            'ref',
            'description',
            'reason',
            'deptno',
            'qty',
            'unitprice',
            'accno',
            'submiteinvoice',
            'einvoiceissuedatetime',
            'consolidatedeinvoice',
            'einvoicevalidationlink'
        ];

        $salesDepositByWalletPaymentEntryReportHeader = [
            'docno',
            'docdate',
            'debtorcode',
            'description',
            'deptno',
            'paymentmethod',
            'paymentamt',
        ];

        $salesDepositByWalletRefundEntryReportHeader = [
            'docno',
            'debtorcode',
            'docdate',
            'description',
            'deptno',
            'paymentmethod',
            'knockoffdoctype',
            'knockoffdocno',
            'knockoffamt',
        ];

        if ($reportType === 'Sales Invoice Report' &&
            $header !== $salesInvoiceHeader &&
            $header !== [...$salesInvoiceHeader, $optionalColumn]) {
            throw new MalformedRequestException('Uploaded Excel file format is incorrect. Column headers do not match expected format.');
        }
        elseif ($reportType === 'Customers Report' && $header !== $customersReportHeader) {
            throw new MalformedRequestException('Uploaded Excel file format is incorrect. Column headers do not match expected format.');
        }
        elseif ($reportType === '01R - RECEIVE PAYMENT [AR RECEIVE PAYMENT]' && $header !== $paymentReportHeader) {
            throw new MalformedRequestException('Uploaded Excel file format is incorrect. Column headers do not match expected format.');
        }
        elseif ($reportType === 'Credit Note Report' && $header !== $creditNoteReportHeader) {
            throw new MalformedRequestException('Uploaded Excel file format is incorrect. Column headers do not match expected format.');
        }
        elseif ($reportType === '01DRW - Sales Deposit by Wallet [AR PAYMENT ENTRY]' && $header !== $salesDepositByWalletPaymentEntryReportHeader) {
            throw new MalformedRequestException('Uploaded Excel file format is incorrect. Column headers do not match expected format.');
        }
        elseif ($reportType === '01DRF - Sales Deposit by Wallet [AR REFUND ENTRY]' && $header !== $salesDepositByWalletRefundEntryReportHeader) {
            throw new MalformedRequestException('Uploaded Excel file format is incorrect. Column headers do not match expected format.');
        }
    }
}
