<?php

class PromotionController extends Controller
{
    public function index(): void
    {
        Auth::requirePermission('menu', 'view');

        $promotionModel = new Promotion();
        $this->view('promotions.index', [
            'pageTitle'   => 'Home Promotions',
            'promotions'  => $promotionModel->allOrdered(),
            'csrf'        => $this->csrfField(),
        ]);
    }

    public function store(): void
    {
        Auth::requirePermission('menu', 'edit');
        $this->verifyCsrf();

        $title = trim($this->input('title', ''));
        if ($title === '') {
            $this->redirect('promotions');
            return;
        }

        $promotionModel = new Promotion();
        $promotionModel->insert([
            'title'         => $title,
            'subtitle'      => trim($this->input('subtitle', '')) ?: null,
            'button_text'   => trim($this->input('button_text', 'Browse Menu')) ?: 'Browse Menu',
            'image_path'    => $this->handleImageUpload(),
            'display_order' => $promotionModel->nextDisplayOrder(),
            'is_active'     => 1,
        ]);

        AuditLogger::log(Auth::id(), 'PROMOTION_CREATE', 'menu', "Added promotion: {$title}");
        $this->redirect('promotions');
    }

    public function update(): void
    {
        Auth::requirePermission('menu', 'edit');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $promotionModel = new Promotion();
        $existing = $promotionModel->find($id);
        if (!$existing) {
            $this->redirect('promotions');
            return;
        }

        $newImage = $this->handleImageUpload();
        $data = [
            'title'         => trim($this->input('title', $existing['title'])),
            'subtitle'      => trim($this->input('subtitle', '')) ?: null,
            'button_text'   => trim($this->input('button_text', 'Browse Menu')) ?: 'Browse Menu',
            'display_order' => (int) $this->input('display_order', $existing['display_order']),
        ];
        if ($newImage) {
            $this->deleteUploadedImage($existing['image_path']);
            $data['image_path'] = $newImage;
        }

        $promotionModel->update($id, $data);
        AuditLogger::log(Auth::id(), 'PROMOTION_UPDATE', 'menu', "Updated promotion #{$id}");
        $this->redirect('promotions');
    }

    public function toggle(): void
    {
        Auth::requirePermission('menu', 'edit');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $promotionModel = new Promotion();
        $promo = $promotionModel->find($id);
        if ($promo) {
            $promotionModel->update($id, ['is_active' => $promo['is_active'] ? 0 : 1]);
        }
        $this->redirect('promotions');
    }

    public function delete(): void
    {
        Auth::requirePermission('menu', 'delete');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $promotionModel = new Promotion();
        $promo = $promotionModel->find($id);
        if ($promo) {
            $this->deleteUploadedImage($promo['image_path']);
            $promotionModel->delete($id);
            AuditLogger::log(Auth::id(), 'PROMOTION_DELETE', 'menu', "Deleted promotion #{$id}");
        }
        $this->redirect('promotions');
    }

    private function handleImageUpload(): ?string
    {
        if (empty($_FILES['image']) || $_FILES['image']['error'] === UPLOAD_ERR_NO_FILE) {
            return null;
        }
        if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) {
            return null;
        }

        $allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
        $mime = mime_content_type($_FILES['image']['tmp_name']);
        if (!isset($allowed[$mime])) {
            return null;
        }
        if ($_FILES['image']['size'] > 3 * 1024 * 1024) {
            return null;
        }

        $ext = $allowed[$mime];
        $filename = 'promo_' . bin2hex(random_bytes(8)) . '.' . $ext;
        $uploadDir = ROOT_PATH . '/public/uploads/promotions/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        if (!move_uploaded_file($_FILES['image']['tmp_name'], $uploadDir . $filename)) {
            return null;
        }

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

    private function deleteUploadedImage(?string $relativePath): void
    {
        if (!$relativePath) {
            return;
        }
        $fullPath = ROOT_PATH . '/public/' . $relativePath;
        if (is_file($fullPath)) {
            @unlink($fullPath);
        }
    }
}
