<?php
declare(strict_types=1);

require_once __DIR__ . '/../../security/auth_guard.php';
require_once __DIR__ . '/../../config/constants.php';
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../../core/Response.php';
require_once __DIR__ . '/../../core/Validator.php';
require_once __DIR__ . '/../../core/Logger.php';

$db = Database::getInstance();

/**
 * ----------------------------
 * Method check
 * ----------------------------
 */
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    Response::error('Invalid request method', 405);
}

/**
 * ----------------------------
 * Required fields
 * ----------------------------
 */
Validator::required($_POST, [
    'id',
    'title',
    'short_description',
    'description',
    'offer_price',
    'start_date',
    'end_date',
    'redirect_url',
    'status'
]);

$offerId = (int) $_POST['id'];

/**
 * ----------------------------
 * Date validation
 * ----------------------------
 */
if (strtotime($_POST['end_date']) <= strtotime($_POST['start_date'])) {
    Response::error('End date must be greater than start date', 422);
}

/**
 * ----------------------------
 * Fetch existing offer
 * ----------------------------
 */
$stmt = $db->prepare("
    SELECT desktop_image, mobile_image
    FROM offers
    WHERE id = :id AND deleted_at IS NULL
");
$stmt->execute(['id' => $offerId]);

$offer = $stmt->fetch();
if (!$offer) {
    Response::error('Offer not found', 404);
}

/**
 * ----------------------------
 * Image validation helper
 * ----------------------------
 */
function validateImage(array $file): void
{
    if ($file['error'] !== UPLOAD_ERR_OK) {
        Response::error('Image upload failed');
    }

    if ($file['size'] > MAX_IMAGE_SIZE) {
        Response::error('Image size exceeds limit');
    }

    $mime = mime_content_type($file['tmp_name']);
    if (!in_array($mime, ALLOWED_IMAGE_TYPES, true)) {
        Response::error('Invalid image type');
    }
}

/**
 * ----------------------------
 * Upload directory
 * ----------------------------
 */
$uploadDir = BASE_PATH . '/uploads/offers/';

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

/**
 * ----------------------------
 * Track image paths
 * ----------------------------
 */
$newDesktopImage = $offer['desktop_image'];
$newMobileImage  = $offer['mobile_image'];

$oldDesktopPath = str_replace(BASE_URL, BASE_PATH, $offer['desktop_image']);
$oldMobilePath  = str_replace(BASE_URL, BASE_PATH, $offer['mobile_image']);

/**
 * ----------------------------
 * Desktop image replace
 * ----------------------------
 */
if (!empty($_FILES['desktop_image']['tmp_name'])) {

    validateImage($_FILES['desktop_image']);

    $desktopFile = 'desktop_' . uniqid('', true) . '.webp';

    if (!move_uploaded_file(
        $_FILES['desktop_image']['tmp_name'],
        $uploadDir . $desktopFile
    )) {
        Response::error('Failed to upload desktop image');
    }

    $newDesktopImage = BASE_URL . UPLOAD_BASE_URL . '/offers/' . $desktopFile;
}

/**
 * ----------------------------
 * Mobile image replace
 * ----------------------------
 */
if (!empty($_FILES['mobile_image']['tmp_name'])) {

    validateImage($_FILES['mobile_image']);

    $mobileFile = 'mobile_' . uniqid('', true) . '.webp';

    if (!move_uploaded_file(
        $_FILES['mobile_image']['tmp_name'],
        $uploadDir . $mobileFile
    )) {
        Response::error('Failed to upload mobile image');
    }

    $newMobileImage = BASE_URL . UPLOAD_BASE_URL . '/offers/' . $mobileFile;
}

/**
 * ----------------------------
 * Update DB
 * ----------------------------
 */
try {
    $stmt = $db->prepare("
        UPDATE offers SET
            title = :title,
            short_description = :short_description,
            description = :description,
            offer_price = :offer_price,
            start_date = :start_date,
            end_date = :end_date,
            desktop_image = :desktop_image,
            mobile_image = :mobile_image,
            redirect_url = :redirect_url,
            status = :status,
            updated_at = NOW()
        WHERE id = :id
    ");

    $stmt->execute([
        'id'                => $offerId,
        'title'             => trim($_POST['title']),
        'short_description' => trim($_POST['short_description']),
        'description'       => $_POST['description'],
        'offer_price'       => $_POST['offer_price'],
        'start_date'        => $_POST['start_date'],
        'end_date'          => $_POST['end_date'],
        'desktop_image'     => $newDesktopImage,
        'mobile_image'      => $newMobileImage,
        'redirect_url'      => $_POST['redirect_url'],
        'status'            => $_POST['status']
    ]);

} catch (Throwable $e) {
    Logger::error('Offer update failed', ['error' => $e->getMessage()]);
    Response::error('Failed to update offer', 500);
}

/**
 * ----------------------------
 * Cleanup old images (only if replaced)
 * ----------------------------
 */
if (
    $newDesktopImage !== $offer['desktop_image'] &&
    file_exists($oldDesktopPath)
) {
    unlink($oldDesktopPath);
}

if (
    $newMobileImage !== $offer['mobile_image'] &&
    file_exists($oldMobilePath)
) {
    unlink($oldMobilePath);
}

/**
 * ----------------------------
 * Response
 * ----------------------------
 */
Logger::auth('Offer updated', [
    'offer_id' => $offerId,
    'by'       => $_SESSION['employee_id']
]);

Response::success('Offer updated successfully');
