<?php

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

use App\Maintenance\TextFile;
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Common\Type;
use Carbon\Carbon;

use App\Models\SaleSummary;
use App\Models\EndingInventory;
use App\Models\UserBranch;
use App\Models\Company;
use App\Models\CompanyBranch;

use Log;

class RecordEndingInventory extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $params;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($params)
    {
        $this->params = $params;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $companyCode = $this->params['company_code'];
        $branchCode = $this->params['branch_code'];
        $type = $this->params['type'];
        $uniqueCode = $this->params['unique_code'];

        $date = Carbon::parse($this->params['date'])->toDateString();

        $branchInventoryForRecording = TextFile::where('unique_code', $uniqueCode)
            ->where('uploaded', true)
            ->where('intended', false)
            ->get();

        $company = Company::where('company_code', $companyCode)->first();
        $branch = CompanyBranch::where('branch_code', $companyCode . '' . $branchCode)->first();

        $transformed = [
            'Company Code' => $companyCode,
            'Company Name' => empty($company) ? null : $company->company,
            'Branch Code' => $companyCode . $branchCode,
            'Branch Name' => empty($branch) ? null : $branch->branch
        ];

        $started = Carbon::now()->toDateTimeString();

        $result = '';

        foreach ($branchInventoryForRecording as $branchInventory) {
            $path = $branchInventory->path;

            $reader = ReaderFactory::create(Type::CSV);
            $reader->setFieldDelimiter('|');
            $reader->open($path);

            $cancelled = '0';
            $errorMessage = [];

            foreach ($reader->getSheetIterator() as $sheet) {
                foreach ($sheet->getRowIterator() as $row) {
                    if (!($this->codeTransformer($row[0], 'company') == $companyCode)) {
                        $errorMessage[] = "INVALID COMPANY CODE";
                    }
                    if (!($this->codeTransformer($row[2], 'branch') == $branchCode)) {
                        $errorMessage[] = "INVALID BRANCH CODE";
                    }
                    if (!($date == Carbon::parse($row[6])->toDateString())) {
                        $errorMessage[] = "INVALID DATE";
                    }
                    if (!empty($errorMessage)) {
                        $cancelled = '1';
                    }
                    break;
                }
                break;
            }

            if($transformed['Branch Name'] == null) {
                $cancelled = '1';
                $errorMessage[] = "BRANCH NOT FOUND";
            }

            if($transformed['Company Name'] == null) {
                $cancelled = '1';
                $errorMessage[] = "COMPANY NOT FOUND";
            }

            if ($cancelled == '0') {
                foreach ($reader->getSheetIterator() as $sheet) {
                    foreach ($sheet->getRowIterator() as $row) {

                        EndingInventory::updateOrCreate([
                            'company_code' => $transformed['Company Code'],
                            'company_name' => $transformed['Company Name'],
                            'branch_code' => $transformed['Branch Code'],
                            'branch_name' => $transformed['Branch Name'],
                            'barcode' => $row[4],
                            'itemcode' => $row[7],
                            'beginning' => 0,
                            'ending' => $row[5],
                            'date' => $date,
                            'description' => $row[8],
                            'department' => $row[9],
                            'category' => $row[10],
                            'brand' => $row[11],
                            'cost' => $row[12],
                            'srp' => $row[13]
                        ]);
                    }
                }

                $branchInventory->intended = true;
                $branchInventory->intended_status = "Recorded As Of : " . Carbon::now()->toDayDateTimeString();
                $branchInventory->save();

                $finished = Carbon::now()->toDateTimeString();

                $result = "ENDING INVENTORY RECORDING SUCCESSFUL : " .
                    "ENDING INVENTORY OF : " . $date . " | " .
                    $transformed['Company Code'] .
                    ' | ' . $transformed['Branch Code'] .
                    " | " . "Started : " . $started .
                    " | " . "Finished : " . $finished;
            }

            if ($cancelled == '1') {
                $branchInventory->intended_status = "File Error : " . implode(" | ", $errorMessage);
                $branchInventory->save();

                $finished = Carbon::now()->toDateTimeString();

                $result = "ENDING INVENTORY RECORDING FAILED WITH ERRORS : " . implode(" | ", $errorMessage) . " | " .
                    "ENDING INVENTORY OF : " . $date . " | " .
                    $transformed['Company Code'] .
                    ' | ' . $transformed['Branch Code'] .
                    " | " . "Started : " . $started .
                    " | " . "Finished : " . $finished;
            }

        }

        Log::info($result);
    }

    public function codeTransformer($code, $type)
    {
        $transformedCode = $code;

        switch($type){
            case 'year' :

            case 'company':

            case 'branch': $transformedCode = str_pad($code, 4, "0", STR_PAD_LEFT); break;

            case 'month':

            case 'terminal': $transformedCode = str_pad($code, 2, "0", STR_PAD_LEFT); break;

            case 'transactionNumber': $transformedCode = str_pad($code, 10, "0", STR_PAD_LEFT); break;

            default: $transformedCode = str_pad($code, 4, "0", STR_PAD_LEFT); break;
        }

        return $transformedCode;
    }
}