<?php

namespace App\Http\Controllers\Imports;

use DateTime;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Company;
use App\Models\Segment;
use App\Models\Transaction;
use Illuminate\Http\Request;
use App\Models\SeasonalSegment;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\TransactionMappingLog;
use App\Models\StatementTransactionOwner;
use App\Classes\ValueObjects\Constants\HttpStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Imports\Services\GenericImport;
use App\Classes\ValueObjects\Response\ApiResponseObject;
use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment;
use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;

class ImportStatementReceiptsController
{
    private $responseTitle;
    private $responseMessage;

    private $removeStr = 'Payment for ';

    public function __construct() {
        $this->responseTitle = 'Import Receipt Mapping';
        $this->responseMessage = 'You have successfully imported receipt mapping';
    }

    /**
     * @param Request $request
     * @return array
     * @throws \App\Classes\Exceptions\MalformedRequestException
     */
    public function import(Request $request)
    {
        try {
            $importDate = date('Y-m-d H:i:s');
            $object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
            $file = json_decode($object->getFiles()[0])->file_info->original->file;

            $import = new GenericImport();
            Excel::import($import, $file);
            $excelRows = $import->rows;
            $excelRows = $excelRows->toArray();

            $data = [];
            foreach ($excelRows as $row) {
                $row['mapped_result_reference'] = null;
                $row['mapped_status'] = 'failed';
                $row['date'] = in_array(gettype($row['doc_date']), ['integer', 'double']) ? $this->changeExcelDate($row['doc_date']) : date('Y-m-d', strtotime($row['doc_date']));

                if ($invRefer = $this->getInvoiceReference($row['description'])) {
                    $returnReference = $this->mappingExchange($invRefer, $row['doc_no']);
                    if ($returnReference) {
                        $row['mapped_result_reference'] = $returnReference;
                        $row['mapped_status'] = 'success';
                    } 
                }

                TransactionMappingLog::create([
                    'imported_date'=>$importDate,
                    'type' => 'receipts',
                    'data'=>$row,
                ]);
                array_push($data, $row);
            }

            return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]);
        }  catch (\Exception $exception){
            return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR));
        }
    }

    private function getInvoiceReference($invRefer) {
        $arrStr = explode($this->removeStr, $invRefer);
        if (isset($arrStr[1])) return $arrStr[1];
        return null;
    }

    public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse {
        return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler();
    }

    private function mappingExchange($invRefer, $docNo) {
        $transactionOwner = StatementTransactionOwner::where('invoice_reference',$invRefer)->whereNull('receipt_reference')->where('status', ApprovalStatus::COMPLETED)->first();

        if ($transactionOwner) {
            return $this->updateTransactionOwnerReference($transactionOwner, $docNo);
        }
        return false;
    }

    public function updateTransactionOwnerReference($transactionOwner, String $docNo) {
        if ($transactionOwner) {
            $transactionOwner->update([
                'receipt_reference'=>$docNo,
                'status'=>ApprovalStatus::COMPLETED
            ]);
            return $transactionOwner->owner_reference;
        }
        return false;
    }

    public function changeExcelDate($date)
    {
        $unixTime = (($date - 25569) * 86400);
        $date = new DateTime("@$unixTime");
        return $date->format('Y-m-d'); // Change the format to 'Y-m-d'
    }
}
