<?php

namespace App\Jobs;

use App\Models\Download;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;

class ProcessDownload implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $timeout = 600;

    /**
     * @var Download
     */
    protected $download;

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

    private function liveExecuteCommand(Download $download, $cmd)
    {
        while (@ ob_end_flush()); // end all output buffers if any

        $proc = popen("$cmd && echo FINISH", 'r');
        $error = true;

        while ($line = fgets($proc))
        {
            $line = preg_replace("/\s+/", " ", $line);
            $parts = explode(' ', $line);
            //echo '<span style="color: red;">'.print_r($parts, true).'</span><br/>';
            if(count($parts) > 1) {
                if($parts[0] == '[download]') {

                    if($parts[1] == 'Destination:') {
                        $filename = basename(implode(' ', array_slice($parts, 2)));
                        echo $filename."\n";
                        $filename_without_ext = substr($filename, 0, strrpos($filename, '.'));
                        $download->name = str_replace('_', ' ', $filename_without_ext);
                        $download->path = $filename_without_ext.'.mp3';
                        echo "Title => " . $download->name;
                        $download->save();
                        DB::commit();
                    } else {
                        //echo "Progress => " . $parts[1];
                        $progress = floatval($parts[1]);
                        if($progress >= 100) {
                            $download->progress_value = 100;
                            $download->status = 'encoding';
                            $error = false;
                        } else {
                            $download->status = 'in_progress';
                            $download->progress_value = ceil($progress);
                        }

                        $download->save();
                        DB::commit();
                    }
                }
            }
            //echo "<br/>";
            @flush();
        }

        pclose($proc);

        if(!$error) {
            $download->status = 'completed';
        } else {
            $download->status = 'in_error';
        }
        $download->save();
        DB::commit();
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            if($this->download->status == 'pending') {
                $this->download->progress_value = 0;
                $this->download->status = 'in_progress';
                $this->download->save();

                if($this->download) {
                    $url = 'https://youtu.be/' . $this->download->uniqid;
                    $cmd = 'youtube-dl --newline -o "' . storage_path('files/%(title)s.%(ext)s') . '" --extract-audio -x --audio-format mp3 "' . $url . '"';
                    $this->liveExecuteCommand($this->download, $cmd);
                } else {
                    $this->download->status = 'in_error';
                    $this->download->save();
                }
            }
            /*$proc_file = storage_path('temp/proc_'.$this->download->uniqid);

            file_put_contents($proc_file, json_encode(['id' => $this->download->uniqid, 'progress' => 0, 'step' => 'downloading']));

            if(is_readable($proc_file)) {
                $infos = json_decode(file_get_contents($proc_file));

                //$url = 'https://youtu.be/' . $name;

                while ($infos->progress < 100) {
                    sleep(1);
                    $infos->progress+=10;
                    //file_put_contents($proc_file, json_encode($infos));
                    $this->download->progress_value = $infos->progress;
                    $this->download->save();
                    DB::commit();
                }

                $infos->progress = 100;
                $infos->step = "encoding";
                //file_put_contents($proc_file, json_encode($infos));
                $this->download->progress_value = 100;
                $this->download->status = 'completed';
                $this->download->save();
            } else {
                $this->download->status = 'in_error';
                $this->download->save();
            }*/
        } catch (\Exception $ex) {
            echo $ex->getMessage();
            $this->download->status = 'in_error';
            $this->download->save();
        }
            //exec('youtube-dl --verbose -o "' . storage_path('temp/temp__%(title)s.%(ext)s') . '" --extract-audio -x --audio-format mp3 "' . $url . '" > ' . storage_path('logs/debug.log'), $output, $resultcode);

        //exec('youtube-dl --verbose -o "' . storage_path('temp/temp__%(title)s.%(ext)s') . '" --extract-audio -x --audio-format mp3 "' . $url . '" > ' . storage_path('logs/debug.log'), $output, $resultcode);
    }
}
