<?php

namespace App\Libs\Services;

use App\Models\Document;
use App\Models\Letter;
use App\Models\User;
use App\Notifications\NewLetterUploaded;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;

class LetterService
{
    public function findLetterById($letterId)
    {
        $letter = Letter::find($letterId);
        return $letter;
    }

    public function getLetters($data)
    {
        $orderDir = $data['orderDir'] ? $data['orderDir'] : 'asc';
        $now = Carbon::now();

        $query = Letter::select('*');

        if (!empty($data['letterType']) && $data['letterType'] !== 'all') {
            $query->where('letter_type', $data['letterType']);
        }

        if (!empty($data['filterBy'])) {
            switch ($data['filterBy']) {
                case 'closed':
                    $query->whereDate('open_until', '<', $now);
                    break;
                case 'open':
                    $query->whereDate('open_until', '>=', $now);
                    break;
            }
        }

        switch ($data['orderBy']) {
            case 'publicationDate':
                $query->orderBy('publication_date', $orderDir);
                break;
            case 'open_until':
                $query->orderBy('open_until', $orderDir);
                break;
            case 'createdAt':
                $query->orderBy('created_at', $orderDir);
                break;
            default:
                # title
                $query->orderBy('title', $orderDir);
                break;
        }

        $perPage = $data['perPage'] ?? 12;
        $page = $data['page'] ?? 1;

        $letters = $query->paginate($perPage, ['*'], 'page', $page);

        $paginationData = [
            'currentPage' =>  intval($letters->currentPage()),
            'lastPage' => intval($letters->lastPage()),
            'perPage' =>  intval($letters->perPage()),
            'total' =>  intval($letters->total()),
            'count' =>  intval($letters->count()),
            'hasMorePages' => $letters->hasMorePages(),
            'nextPageUrl' => $letters->nextPageUrl(),
            'prevPageUrl' => $letters->previousPageUrl(),
        ];

        return [
            'letters' => $letters,
            'pagination' => $paginationData,
        ];
    }

    public function createLetter($data)
    {
        $tempFileName = $data['filename'];
        $tempPath = 'temp_document/' . $tempFileName;
        $ext = pathinfo($data['filename'], PATHINFO_EXTENSION);
        $uniqueName = md5(pathinfo($data['filename'], PATHINFO_FILENAME) . microtime(true));
        $newFileName = $uniqueName . '.' . $ext;

        $finalPath = 'letters/' . $newFileName;

        $privateDisk = Storage::disk('private');

        if (!$privateDisk->exists(dirname($finalPath))) {
            $privateDisk->makeDirectory(dirname($finalPath));
        }

        if ($privateDisk->exists($tempPath)) {
            $privateDisk->move($tempPath, $finalPath);
        } else {
            return [];
        }

        $fileSize = $privateDisk->size($finalPath);

        $document = Document::create([
            'filename'              => $newFileName,
            'original_filename'     => $tempFileName,
            'extension'             => $ext,
            'size'                  => $fileSize,
        ]);

        $letter = Letter::create([
            'title'             => $data['title'],
            'publication_date'  => $data['publicationDate'],
            'open_until'        => $data['openUntil'],
            'letter_type'       => $data['letterType'],
            'document_id'       => $document->id,
            'user_id'           => Auth::user()->id,
        ]);

        $users = User::where('role', '!=', 'super')->get();
        Notification::send($users, new NewLetterUploaded($letter));


        return $letter;
    }

    public function updateLetter($data)
    {
        $letter = Letter::find($data['id']);

        if (empty($letter)) {
            return null;
        }

        if ($data['filename'] !== $letter->document->filename) {
            $letterOld = $letter->document->filename;
            $tempFileName = $data['filename'];
            $tempPath = 'temp_document/' . $tempFileName;
            $finalPath = 'letters/' . $tempFileName;

            $privateDisk = Storage::disk('private');

            if ($privateDisk->exists($tempPath)) {
                $privateDisk->move($tempPath, $finalPath);

                $fileSize = $privateDisk->size($finalPath);

                $document = Document::find($letter->document->id);
                $document->filename = $tempFileName;
                $document->original_filename = $tempFileName;
                $document->extension = pathinfo($tempFileName, PATHINFO_EXTENSION);
                $document->size = $fileSize;
                $document->save();
            } else {
                return [];
            }

            $filePath = 'letters/' . $letterOld;
            if ($privateDisk->exists($filePath)) {
                $privateDisk->delete($filePath);
            }
        }

        $letter->title = $data['title'];
        $letter->publication_date = $data['publicationDate'];
        $letter->open_until = $data['openUntil'];
        $letter->letter_type = $data['letterType'];
        $letter->save();

        return $letter;
    }

    public function deleteLetter($letterId)
    {
        $letter = Letter::find($letterId);
        if ($letter) {
            $letter->delete();

            $document = $letter->document;

            if ($document) {
                $document->delete();

                $privateDisk = Storage::disk('private');
                $letterOld = $letter->document->filename;
                $filePath = 'letters/' . $letterOld;

                if ($privateDisk->exists($filePath)) {
                    $privateDisk->delete($filePath);
                }
            }
        }

        return [
            'message' => 'success',
        ];
    }
}
