<?php
declare(strict_types=1);

namespace App\Modules\News\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\News\Models\NewsArticle;

class NewsController extends Controller
{
    /**
     * List articles with filters.
     */
    public function index(Request $request): Response
    {
        $filters = [
            'q'            => trim((string) $request->get('q', '')),
            'category'     => trim((string) $request->get('category', '')),
            'is_published' => $request->get('is_published', ''),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = NewsArticle::search($filters, 20, $page);

        return $this->view('News.Views.index', [
            'articles'   => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
            'categories' => NewsArticle::getCategoryLabels(),
        ]);
    }

    /**
     * Show create article form.
     */
    public function create(Request $request): Response
    {
        return $this->view('News.Views.create', [
            'categories' => NewsArticle::getCategoryLabels(),
        ]);
    }

    /**
     * Store a new article.
     */
    public function store(Request $request): Response
    {
        $titleAr  = trim((string) $request->post('title_ar', ''));
        $bodyAr   = trim((string) $request->post('body_ar', ''));
        $category = trim((string) $request->post('category', 'general'));

        // Validation
        $errors = [];
        if ($titleAr === '') {
            $errors[] = 'عنوان الخبر مطلوب';
        }
        if ($bodyAr === '') {
            $errors[] = 'محتوى الخبر مطلوب';
        }
        $validCategories = array_keys(NewsArticle::getCategoryLabels());
        if (!in_array($category, $validCategories, true)) {
            $errors[] = 'فئة الخبر غير صالحة';
        }

        // Handle cover image upload
        $coverImagePath = null;
        if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) {
            $coverImagePath = $this->handleImageUpload($_FILES['cover_image'], $errors);
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/news/create');
        }

        $employee = App::getInstance()->currentEmployee();

        $article = NewsArticle::create([
            'title_ar'         => $titleAr,
            'body_ar'          => $bodyAr,
            'category'         => $category,
            'cover_image_path' => $coverImagePath,
            'is_published'     => 0,
            'created_by'       => $employee ? ($employee->id ?? ($employee['id'] ?? null)) : null,
        ]);

        return $this->redirect('/news/' . $article->id)->withSuccess('تم إنشاء الخبر بنجاح');
    }

    /**
     * Show a single article.
     */
    public function show(Request $request, string $id): Response
    {
        $article = NewsArticle::find((int) $id);
        if (!$article) {
            return $this->redirect('/news')->withError('الخبر غير موجود');
        }

        return $this->view('News.Views.show', [
            'article'    => $article,
            'categories' => NewsArticle::getCategoryLabels(),
        ]);
    }

    /**
     * Show edit form.
     */
    public function edit(Request $request, string $id): Response
    {
        $article = NewsArticle::find((int) $id);
        if (!$article) {
            return $this->redirect('/news')->withError('الخبر غير موجود');
        }

        return $this->view('News.Views.edit', [
            'article'    => $article,
            'categories' => NewsArticle::getCategoryLabels(),
        ]);
    }

    /**
     * Update an article.
     */
    public function update(Request $request, string $id): Response
    {
        $article = NewsArticle::find((int) $id);
        if (!$article) {
            return $this->redirect('/news')->withError('الخبر غير موجود');
        }

        $titleAr  = trim((string) $request->post('title_ar', ''));
        $bodyAr   = trim((string) $request->post('body_ar', ''));
        $category = trim((string) $request->post('category', 'general'));

        // Validation
        $errors = [];
        if ($titleAr === '') {
            $errors[] = 'عنوان الخبر مطلوب';
        }
        if ($bodyAr === '') {
            $errors[] = 'محتوى الخبر مطلوب';
        }

        $updateData = [
            'title_ar' => $titleAr,
            'body_ar'  => $bodyAr,
            'category' => $category,
        ];

        // Handle cover image upload
        if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) {
            $coverImagePath = $this->handleImageUpload($_FILES['cover_image'], $errors);
            if ($coverImagePath !== null) {
                $updateData['cover_image_path'] = $coverImagePath;
            }
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/news/' . $id . '/edit');
        }

        $article->update($updateData);

        return $this->redirect('/news/' . $id)->withSuccess('تم تحديث الخبر بنجاح');
    }

    /**
     * Toggle publish status.
     */
    public function togglePublish(Request $request, string $id): Response
    {
        $article = NewsArticle::find((int) $id);
        if (!$article) {
            return $this->redirect('/news')->withError('الخبر غير موجود');
        }

        $isPublished = (int) $article->is_published;

        if ($isPublished) {
            // Unpublish
            $article->update([
                'is_published' => 0,
                'published_at' => null,
            ]);
            $message = 'تم إلغاء نشر الخبر';
        } else {
            // Publish
            $article->update([
                'is_published' => 1,
                'published_at' => date('Y-m-d H:i:s'),
            ]);
            $message = 'تم نشر الخبر بنجاح';
        }

        return $this->redirect('/news/' . $id)->withSuccess($message);
    }

    /**
     * Handle image upload. Returns the saved path or null.
     */
    private function handleImageUpload(array $file, array &$errors): ?string
    {
        $allowedTypes = ['image/jpeg', 'image/png', 'image/jpg'];
        $maxSize = 5 * 1024 * 1024; // 5MB

        if (!in_array($file['type'], $allowedTypes, true)) {
            $errors[] = 'نوع الصورة غير مدعوم (يُسمح فقط بـ JPG و PNG)';
            return null;
        }

        if ($file['size'] > $maxSize) {
            $errors[] = 'حجم الصورة يتجاوز الحد المسموح (5 ميجابايت)';
            return null;
        }

        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = 'news_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
        $uploadDir = rtrim((string) ($_ENV['UPLOAD_PATH'] ?? 'public/uploads'), '/') . '/news';

        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        $destPath = $uploadDir . '/' . $filename;
        if (!move_uploaded_file($file['tmp_name'], $destPath)) {
            $errors[] = 'فشل في رفع الصورة';
            return null;
        }

        return '/uploads/news/' . $filename;
    }
}
