<?php

namespace App\Classes\Modules\Bookings\ControllersLogic;


use App\Classes\ValueObjects\Constants\TransactionType;
use Illuminate\Support\Facades\File;
use ZipArchive;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Booking;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use Illuminate\Support\Facades\Log;

class DownloadBookingDocumentLogic
{


    /**
     * @param Request $request
     * @return void
     * @throws MalformedRequestException
     */
    public function execute(Request $request)
    {
        Auth::login(User::findOrFail(1));
        $document_type = str_replace(' ', '', $request->input('type'));

        $zipDirectory = storage_path('app/documents/collections');

        if (!file_exists($zipDirectory)) {
            mkdir($zipDirectory, 0755, true);
        }

        $zip_file = $document_type.'.zip';
        // $attachment = storage_path().'/app/documents/collections/' . $zip_file;
        // Log::info('attachment 1: '. $attachment);
        $attachment = "{$zipDirectory}/{$zip_file}";
        Log::info('attachment: '. $attachment);

        $bookings = Booking::where('status', ApprovalStatus::COMPLETED)
        ->whereDate('created_at', '>=', Carbon::parse($request->input('startDate')))
        ->whereDate('created_at', '<=', Carbon::parse($request->input('endDate')))
        ->whereHas('transactions', function ($query) use ($request){
            return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query) use ($request){
                return $query->where('type', TransactionType::BILL)->where('issuer', $request->input('supplier'));
            });
        })->get();

        if (!count($bookings)) {
            return response()->json(['no file to download']);
        }

        $filesystemDriver = Storage::getDefaultDriver();
        if($filesystemDriver === 's3'){
            $zip = new ZipArchive();
            if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
                foreach ($bookings as $booking) {

                    if ($document_type == 'INVOICEPODO' || $document_type == 'INVOICEPODOSDO') {
                        $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->first()->files()->first();
                        $purchase_file = $booking->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()->files()->first();
                        $deliver_file = $booking->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()->files()->first();
                        if ($document_type == 'INVOICEPODOSDO') {
                            $supplier_deliver_order_file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first();
                        }
                        $fileContent = Storage::disk('s3')->get($invoice_file->file->file_info->original->file);
                        $zip->addFromString('invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);

                        $fileContent = Storage::disk('s3')->get($purchase_file->file->file_info->original->file);
                        $zip->addFromString('purchase-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);

                        $fileContent = Storage::disk('s3')->get($deliver_file->file->file_info->original->file);
                        $zip->addFromString('deliver-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);

                        $fileContent = Storage::disk('s3')->get($supplier_deliver_order_file->file->file_info->original->file);
                        $zip->addFromString('supplier-deliver-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);
                    }
                    else {
                        $file = $booking->documents()->where('document_type', $document_type)->first()->files()->first();
                        $fileContent = Storage::disk('s3')->get($file->file->file_info->original->file);
                        $zip->addFromString($booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf', $fileContent);
                    }

                }
                $zip->close();

                $filePathForS3 = 'documents/collections/'.$zip_file;
                Storage::disk('s3')->put($filePathForS3, file_get_contents($attachment));

                Log::info('DownloadBookingDocumentLogic finished processing files to zip count: '.count($bookings));

                $temporaryUrl = Storage::disk('s3')->temporaryUrl(
                    $filePathForS3,
                    Carbon::now()->addMinutes(10)
                );

                return response(['src' =>  $temporaryUrl ]);
            }
        }
        else{
            $zip = new ZipArchive();
            if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {

                foreach ($bookings as $booking) {

                    if ($document_type == 'INVOICEPODO' || $document_type == 'INVOICEPODOSDO') {
                        $invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->first()->files()->first();
                        $purchase_file = $booking->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()->files()->first();
                        $deliver_file = $booking->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()->files()->first();
                        if ($document_type == 'INVOICEPODOSDO') {
                            $supplier_deliver_order_file = $booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()->files()->first();
                        }

                        $zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');

                        $zip->addFile(Storage::disk('documents')->path($purchase_file->file->file_info->original->file), 'purchase-order-' .  $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');

                        $zip->addFile(Storage::disk('documents')->path($deliver_file->file->file_info->original->file), 'deliver-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');

                        $zip->addFile(Storage::disk('documents')->path($supplier_deliver_order_file->file->file_info->original->file), 'supplier-deliver-order-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');
                    }
                    else {
                        $file = $booking->documents()->where('document_type', $document_type)->first()->files()->first();
                        $zip->addFile(Storage::disk('documents')->path($file->file->file_info->original->file), $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');
                    }

                }
                $zip->close();
                while (ob_get_level()) {
                    ob_end_clean();
                }
                ob_start();
                header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
                header("Content-Type: application/zip");
                header("Content-Transfer-Encoding: Binary");
                header("Content-Length: " . filesize($attachment));
                header('Pragma: no-cache');
                header("Content-Disposition: attachment; filename=\"" . basename($attachment) . "\"");
                ob_flush();
                ob_clean();

                readfile($attachment);
                File::delete($attachment);

                exit;

                //header('Content-Type: application/zip');
                //header('Content-Length: ' . filesize($attachment));
                //readfile($attachment);
                //unlink($attachment);

            }
        }

    }
}
