<?php

namespace App\Http\Controllers\Admin\News;

use App\Http\Controllers\Controller;
use App\Models\News;
use App\Services\ItemDataService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Inertia\Inertia;

class NewsController extends Controller
{
    public function __construct(
        protected ItemDataService $itemDataService
    ) {}

    public function index()
    {
        $news = News::orderBy('created_at', 'desc')->paginate(10);

        return Inertia::render('admin/news/pages/NewsListPage', [
            'news' => $news,
        ]);
    }

    public function create()
    {
        $itemService = new ItemDataService;
        $items = $itemService->getAllItems(500);

        return Inertia::render('admin/news/pages/NewsCreatePage', [
            'availableItems' => $items,
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'category' => 'required|in:patch,download,guide,promo,event',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
            'content' => 'required|string',
            'is_active' => 'nullable|boolean',
            'show_as_popup' => 'nullable|boolean',
            'popup_delay' => 'nullable|integer|min:0',
            'popup_frequency' => 'nullable|in:once,daily,always',
        ]);

        // If this news should be shown as popup, disable all other popups
        if (filter_var($request->show_as_popup ?? false, FILTER_VALIDATE_BOOLEAN)) {
            News::where('show_as_popup', true)->update(['show_as_popup' => false]);
        }

        $data = [
            'title' => $request->title,
            'category' => $request->category,
            'content' => $request->content,
            'is_active' => filter_var($request->is_active ?? true, FILTER_VALIDATE_BOOLEAN),
            'show_as_popup' => filter_var($request->show_as_popup ?? false, FILTER_VALIDATE_BOOLEAN),
            'popup_delay' => $request->popup_delay ?? 1000,
            'popup_frequency' => $request->popup_frequency ?? 'once',
        ];

        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $baseFilename = time().'_news_'.pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);

            // Store temporarily
            $tempPath = $file->storeAs('temp', $baseFilename.'.'.$file->getClientOriginalExtension(), 'public');
            $fullTempPath = storage_path('app/public/'.$tempPath);

            // Create news directory if it doesn't exist
            $newsDir = storage_path('app/public/news');
            if (! file_exists($newsDir)) {
                mkdir($newsDir, 0755, true);
            }

            // Try to convert to WebP
            $webpPath = $this->convertToWebP($fullTempPath, $newsDir, $baseFilename, 80);
            if ($webpPath) {
                $data['image'] = 'news/'.$baseFilename.'.webp';
            } else {
                // If conversion fails, use original file
                $imagePath = $file->storeAs('news', $baseFilename.'.'.$file->getClientOriginalExtension(), 'public');
                $data['image'] = $imagePath;
                // Clean up temp file
                Storage::disk('public')->delete($tempPath);
            }
        }

        News::create($data);

        return redirect()->route('admin.news.index')->with('success', 'News created successfully.');
    }

    public function edit($id)
    {
        $news = News::findOrFail($id);
        $itemService = new ItemDataService;
        $items = $itemService->getAllItems(500);

        return Inertia::render('admin/news/pages/NewsEditPage', [
            'news' => $news,
            'availableItems' => $items,
        ]);
    }

    public function update(Request $request, $id)
    {
        $news = News::findOrFail($id);

        $request->validate([
            'title' => 'required|string|max:255',
            'category' => 'required|in:patch,download,guide,promo,event',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
            'content' => 'required|string',
            'is_active' => 'nullable|boolean',
            'show_as_popup' => 'nullable|boolean',
            'popup_delay' => 'nullable|integer|min:0',
            'popup_frequency' => 'nullable|in:once,daily,always',
        ]);

        // If this news should be shown as popup, disable all other popups except this one
        if (filter_var($request->show_as_popup ?? false, FILTER_VALIDATE_BOOLEAN)) {
            News::where('show_as_popup', true)
                ->where('id', '!=', $id)
                ->update(['show_as_popup' => false]);
        }

        $data = [
            'title' => $request->title,
            'category' => $request->category,
            'content' => $request->content,
            'is_active' => filter_var($request->is_active, FILTER_VALIDATE_BOOLEAN),
            'show_as_popup' => filter_var($request->show_as_popup ?? false, FILTER_VALIDATE_BOOLEAN),
            'popup_delay' => $request->popup_delay ?? 1000,
            'popup_frequency' => $request->popup_frequency ?? 'once',
        ];

        if ($request->hasFile('image')) {
            // Delete old image if exists
            if ($news->image) {
                Storage::disk('public')->delete($news->image);
            }

            $file = $request->file('image');
            $baseFilename = time().'_news_'.pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);

            // Store temporarily
            $tempPath = $file->storeAs('temp', $baseFilename.'.'.$file->getClientOriginalExtension(), 'public');
            $fullTempPath = storage_path('app/public/'.$tempPath);

            // Create news directory if it doesn't exist
            $newsDir = storage_path('app/public/news');
            if (! file_exists($newsDir)) {
                mkdir($newsDir, 0755, true);
            }

            // Try to convert to WebP
            $webpPath = $this->convertToWebP($fullTempPath, $newsDir, $baseFilename, 80);
            if ($webpPath) {
                $data['image'] = 'news/'.$baseFilename.'.webp';
            } else {
                // If conversion fails, use original file
                $imagePath = $file->storeAs('news', $baseFilename.'.'.$file->getClientOriginalExtension(), 'public');
                $data['image'] = $imagePath;
                // Clean up temp file
                Storage::disk('public')->delete($tempPath);
            }
        }

        $news->update($data);

        return redirect()->route('admin.news.index')->with('success', 'News updated successfully.');
    }

    public function destroy($id)
    {
        $news = News::findOrFail($id);

        // Delete image if exists
        if ($news->image) {
            Storage::disk('public')->delete($news->image);
        }

        $news->delete();

        return back()->with('success', 'News deleted successfully.');
    }

    public function toggleActive($id)
    {
        $news = News::findOrFail($id);
        $news->is_active = ! $news->is_active;
        $news->save();

        return back()->with('success', 'News status updated.');
    }

    public function getActivePopup()
    {
        $popup = News::where('show_as_popup', true)
            ->where('is_active', true)
            ->first();

        return response()->json($popup);
    }

    /**
     * Convert image to WebP format for better compression
     *
     * @param  string  $sourcePath  Full path to source image
     * @param  string  $destinationDir  Directory to save the WebP file
     * @param  string  $baseFilename  Base filename (without extension)
     * @param  int  $quality  WebP quality (0-100)
     * @return string|null Path to the converted WebP file, or null if conversion failed
     */
    private function convertToWebP(string $sourcePath, string $destinationDir, string $baseFilename, int $quality = 80): ?string
    {
        // Check if GD extension is available
        if (! extension_loaded('gd')) {
            return null;
        }

        // Get image info
        $imageInfo = @getimagesize($sourcePath);
        if (! $imageInfo) {
            return null;
        }

        $mimeType = $imageInfo['mime'];

        // Create image resource based on type
        $image = null;
        switch ($mimeType) {
            case 'image/jpeg':
            case 'image/jpg':
                $image = @imagecreatefromjpeg($sourcePath);
                break;
            case 'image/png':
                $image = @imagecreatefrompng($sourcePath);
                // Preserve transparency for PNG
                if ($image) {
                    imagepalettetotruecolor($image);
                    imagealphablending($image, true);
                    imagesavealpha($image, true);
                }
                break;
            case 'image/gif':
                $image = @imagecreatefromgif($sourcePath);
                break;
            case 'image/webp':
                // Already WebP, just move it
                $webpPath = $destinationDir.'/'.$baseFilename.'.webp';
                if (copy($sourcePath, $webpPath)) {
                    @unlink($sourcePath);

                    return $webpPath;
                }

                return null;
            default:
                // Other formats - don't convert
                return null;
        }

        if (! $image) {
            return null;
        }

        // Generate WebP filename
        $webpPath = $destinationDir.'/'.$baseFilename.'.webp';

        // Convert to WebP
        $success = imagewebp($image, $webpPath, $quality);
        imagedestroy($image);

        if ($success) {
            // Delete original file after successful conversion
            @unlink($sourcePath);

            return $webpPath;
        }

        return null;
    }
}
