<?php

namespace App\Jobs;

use App\Models\District;
use App\Models\PhotoReport;
use App\Models\PointPlan;
use App\Models\RequestSet;
use App\Models\User;
use PDF;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;


class GeneratePhotoReport implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    /** Дадим нашему заданию 5 минут */
    public $timeout = 300;      // секунд
    /** Если хотим, чтобы после неудачи задача пробовала ещё раз */
    public $tries = 3;
    protected int $reportId;

    /**
     * Create a new job instance.
     */
    public function __construct(int $reportId)
    {
        $this->reportId = $reportId;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // 1) Получаем модель-отчет
        $report = PhotoReport::findOrFail($this->reportId);
        // 2) Обновляем статус на "processing"
        $report->update(['status' => 'processing']);

        try {
            $requestId = $report->request_id;
            $districtId = $report->district_id;
            $userId = $report->user_id;
            // 1) Собираем встречи PointPlan и связанные файлы
            $plans = PointPlan::with(['point', 'files'])
                ->where('request_id', $requestId)
                ->when($districtId, fn($q) => $q->forDistrict($districtId))
                ->orderBy('day')
                ->get();

            echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Получаем точки и файлы' . "\n");
            $photos = [];
            foreach ($plans as $plan) {
                foreach ($plan->files as $file) {
                    // Пропускаем PDF без thumbnail
                    if ($file->type === "doc") {
                        continue;
                    }
                    $rawPath = $file->thumbnail ?: $file->path;
                    echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . '$file = ' . $file . "\n");
                    echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . '$rawPath = ' . $rawPath . "\n");
                    if (!$file->thumbnail && Str::endsWith(Str::lower($file->path), '.pdf')) {
                        continue;
                    }
                    $url = Str::startsWith($rawPath, ['http://', 'https://'])
                        ? $rawPath
                        : Storage::disk('s3')->url($rawPath);

                    $photos[] = [
                        'url' => $url,
                        'day' => $plan->day->toDateString(),
                        'timeStart' => $plan->timeStart,
                        'point' => [
                            'record_number' => $plan->point->record_number,
                            'name' => $plan->point->name,
                            'latitude' => $plan->point->latitude,
                            'longitude' => $plan->point->longitude,
                        ],
                    ];
                }
            }
            echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Количество элементов в $photos ' . count($photos) . "\n");
            // 2) Закешировать картинки на диск
            $tmpFiles = [];
            foreach ($photos as &$item) {
                try {
                    echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Получаем контент по URL фотографии (' . $item['url'] . ')' . "\n");
                    $contents = @file_get_contents($item['url']);

                    if ($contents) {
                        // 1) Сохраняем на диск (если нужно)

                        $ext = pathinfo(parse_url($item['url'], PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'jpg';
                        $tmpName = 'tmp/photo-report-' . Str::random(16) . '.' . $ext;
                        Storage::disk('local')->put($tmpName, $contents);
                        $item['local_path'] = storage_path("app/{$tmpName}");
                        $tmpFiles[] = $item['local_path'];

                        // 2) Правильно определяем MIME-тип
                        $finfo = finfo_open(FILEINFO_MIME_TYPE);
                        $mime = finfo_buffer($finfo, $contents);
                        finfo_close($finfo);

                        $imagick = new \Imagick();
                        $imagick->readImageBlob($contents);
                        $imagick->autoOrient();      // применит EXIF-ориентацию
                        $oriented = $imagick->getImageBlob();
                        $item['data_uri'] = 'data:' . $mime . ';base64,' . base64_encode($oriented);
                    }
                } catch (\Throwable $e) {
                    echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Ошибка  (' . $e . ')' . "\n");
                    $item['data_uri'] = null;
                }
            }
            unset($item);

            // Найдём менеджера, если передан districtId
            $manager = null;
            if ($districtId) {
                $district = District::with('subgroupManager')->find($districtId);
                // допустим, у District есть relation manager → User
                $manager = $district?->subgroupManager;
            }
            echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Менеджер ' . "$manager" . "\n");

            echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Готовим подпись и печать' . "\n");
            // 3) Подготавливаем base64 для подписи и печати
            $sigPath = storage_path('app/public/images/signature.png');
            $stampPath = storage_path('app/public/images/stamp.png');
            $signatureData = 'data:image/png;base64,' . base64_encode(file_get_contents($sigPath));
            $stampData = 'data:image/png;base64,' . base64_encode(file_get_contents($stampPath));

            echo('  ' . now()->format('Y-m-d H:i:s') . ' ' . 'Генерируем PDF' . "\n");
            // 4) Генерим PDF через Blade-шаблон
            $pdf = Pdf::setOptions([
                'isRemoteEnabled' => true,
                'chroot' => [storage_path('app'), public_path()],
            ])->loadView('reports.photos_pdf', [
                'photos' => $photos,
                'requestId' => $requestId,
                'title' => 'Фотоотчет',
                'subtitle' => $districtId
                    ? District::find($districtId)->name
                    : 'Оренбургская область',
                'manager' => $manager,
                'signatureData' => $signatureData,
                'stampData' => $stampData,
            ]);
            $requestModel = RequestSet::findOrFail($requestId);
            $requestSlug = str_replace(' ', '_', $requestModel->name);

            $districtName = $districtId
                ? District::find($districtId)->name
                : 'Оренбургская область';

            $districtSlug = str_replace(' ', '_', $districtName);
            $date         = now()->format('Y-m-d');
            // вот «красивое» имя, которое попадёт в скачиваемый файл
            $downloadName = "Фотоотчет_{$requestSlug}_{$districtSlug}_{$date}.pdf";

            // 2) ключ в бакете
            $key = "reports/{$downloadName}";

            // 3) сохраняем прямо в S3 и сразу выставляем заголовок ContentDisposition,
            //    чтобы браузер при переходе по URL скачивал именно под этим именем
            Storage::disk('s3')->put($key, $pdf->output(), [
                'ContentType'        => 'application/pdf',
                'ContentDisposition' => 'attachment; filename="'.$downloadName.'"',
            ]);

            // 4) фиксируем в таблице
            $report->update([
                'status'       => 'done',
                'output_path'  => $key,
                'error_message'=> null,
            ]);

            // 6) Очищаем временные файлы
            foreach ($tmpFiles as $file) {
                @unlink($file);
            }

        } catch (\Throwable $e) {
            // при ошибке отмечаем job как `error`
            $report->update(['status' => 'error']);
            \Log::error("PhotoReport #{$this->reportId} fail:", ['exception' => $e]);
            throw $e; // можно перекинуть дальше, чтобы Laravel тоже логнул
        }

        // 4) Уведомляем юзера (простой пример)
        $user = User::find($userId);
        $url = Storage::disk('s3')->url($key);
        $user?->userNotifications()->create([
            'title' => 'Сгенерирован Фотоотчет',
            'content' => "Генерация фотоотчет завершена: Скачать по ссылке $url ",
        ]);
    }
}
