<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\DealModel;
use App\Models\MenuItemModel;
use App\Helpers\ActivityLogger;
use App\Helpers\ImageUploader;
use Core\Request;

final class DealController extends BaseController
{
    private DealModel     $model;
    private MenuItemModel $itemModel;
    private ImageUploader $uploader;

    public function __construct()
    {
        parent::__construct();
        $this->model     = new DealModel();
        $this->itemModel = new MenuItemModel();
        $this->uploader  = new ImageUploader('deals');
    }

    public function index(array $params = []): void
    {
        $this->requirePermission('deal.view');

        $page  = $this->currentPage();
        $deals = $this->model->all($page);
        $total = $this->model->count();

        // Attach items to each deal for display
        foreach ($deals as &$deal) {
            $deal['items'] = $this->model->getDealItems($deal['id']);
        }

        $this->view('deals.index', [
            'pageTitle'   => 'Deals',
            'breadcrumbs' => ['Deals' => null],
            'deals'       => $deals,
            'total'       => $total,
            'page'        => $page,
        ]);
    }

    public function create(array $params = []): void
    {
        $this->requirePermission('deal.create');

        $this->view('deals.form', [
            'pageTitle'   => 'Create Deal',
            'breadcrumbs' => ['Deals' => url('deals'), 'Create' => null],
            'deal'        => null,
            'dealItems'   => [],
            'menuItems'   => $this->getMenuItemsList(),
        ]);
    }

    public function store(array $params = []): void
    {
        $this->requirePermission('deal.create');
        Request::verifyCsrf();

        $errors = $this->validate();
        if ($errors) {
            $this->flash('error', implode('<br>', $errors));
            $this->redirect('/deals/create');
        }

        $title     = Request::str('title');
        $imagePath = null;

        $file = Request::file('deal_image');
        if ($file) {
            $result = $this->uploader->upload($file);
            if (!$result['success']) {
                $this->flash('error', $result['error']);
                $this->redirect('/deals/create');
            }
            $imagePath = $result['path'];
        }

        $id = $this->model->create([
            'title'       => $title,
            'description' => Request::str('description'),
            'deal_price'  => Request::float('deal_price'),
            'deal_image'  => $imagePath,
            'starts_at'   => Request::post('starts_at'),
            'expires_at'  => Request::post('expires_at'),
            'is_active'   => Request::bool('is_active', true) ? 1 : 0,
            'created_by'  => \Core\Auth::id(),
        ]);

        $this->model->saveDealItems($id, $_POST['item_ids'] ?? [], $_POST['item_qtys'] ?? []);

        ActivityLogger::created('deal', $id, $title);
        $this->flash('success', "Deal <strong>{$title}</strong> created successfully.");
        $this->redirect('/deals');
    }

    public function edit(array $params = []): void
    {
        $this->requirePermission('deal.edit');

        $deal = $this->model->find((int)$params['id']);
        if (!$deal) { $this->flash('error', 'Deal not found.'); $this->redirect('/deals'); }

        $this->view('deals.form', [
            'pageTitle'   => 'Edit Deal',
            'breadcrumbs' => ['Deals' => url('deals'), 'Edit' => null],
            'deal'        => $deal,
            'dealItems'   => $this->model->getDealItems($deal['id']),
            'menuItems'   => $this->getMenuItemsList(),
        ]);
    }

    public function update(array $params = []): void
    {
        $this->requirePermission('deal.edit');
        Request::verifyCsrf();

        $id   = (int)$params['id'];
        $deal = $this->model->find($id);
        if (!$deal) { $this->flash('error', 'Deal not found.'); $this->redirect('/deals'); }

        $errors = $this->validate();
        if ($errors) {
            $this->flash('error', implode('<br>', $errors));
            $this->redirect("/deals/{$id}/edit");
        }

        $title     = Request::str('title');
        $imagePath = $deal['deal_image'];

        $file = Request::file('deal_image');
        if ($file) {
            $result = $this->uploader->upload($file);
            if (!$result['success']) {
                $this->flash('error', $result['error']);
                $this->redirect("/deals/{$id}/edit");
            }
            if ($imagePath) $this->uploader->delete($imagePath);
            $imagePath = $result['path'];
        }

        if (Request::post('remove_image') === '1' && $imagePath) {
            $this->uploader->delete($imagePath);
            $imagePath = null;
        }

        $this->model->update($id, [
            'title'       => $title,
            'description' => Request::str('description'),
            'deal_price'  => Request::float('deal_price'),
            'deal_image'  => $imagePath,
            'starts_at'   => Request::post('starts_at'),
            'expires_at'  => Request::post('expires_at'),
            'is_active'   => Request::bool('is_active', true) ? 1 : 0,
        ]);

        $this->model->saveDealItems($id, $_POST['item_ids'] ?? [], $_POST['item_qtys'] ?? []);

        ActivityLogger::updated('deal', $id, $title);
        $this->flash('success', "Deal <strong>{$title}</strong> updated.");
        $this->redirect('/deals');
    }

    public function delete(array $params = []): void
    {
        $this->requirePermission('deal.delete');
        Request::verifyCsrf();

        $id   = (int)$params['id'];
        $deal = $this->model->find($id);
        if (!$deal) { $this->flash('error', 'Deal not found.'); $this->redirect('/deals'); }

        if ($deal['deal_image']) $this->uploader->delete($deal['deal_image']);

        $this->model->delete($id);
        ActivityLogger::deleted('deal', $id, $deal['title']);
        $this->flash('success', 'Deal deleted.');
        $this->redirect('/deals');
    }

    private function validate(): array
    {
        $errors = [];
        if (!Request::str('title'))            $errors[] = 'Deal title is required.';
        if (Request::float('deal_price') <= 0) $errors[] = 'Deal price must be greater than 0.';
        $start  = Request::post('starts_at');
        $expiry = Request::post('expires_at');
        if (!$start || !$expiry)               $errors[] = 'Start and expiry dates are required.';
        elseif ($expiry <= $start)             $errors[] = 'Expiry must be after start date.';
        if (empty($_POST['item_ids']))         $errors[] = 'Add at least one item to the deal.';
        return $errors;
    }

    private function getMenuItemsList(): array
    {
        return $this->db->fetchAll(
            "SELECT mi.id, mi.name, mi.base_price, c.name AS category_name
               FROM menu_items mi
               JOIN categories c ON c.id = mi.category_id
              WHERE mi.is_available = 1
              ORDER BY c.sort_order ASC, mi.name ASC"
        );
    }
}
