<?php
declare(strict_types=1);

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

$db = Database::getInstance();

/* ================= INPUT ================= */
$data = json_decode(file_get_contents('php://input'), true);

if (!is_array($data)) {
    Response::error('Invalid JSON payload', 400);
}

/* ================= REQUIRED ================= */
if (!isset($data['blog_id'])) {
    Response::error('blog_id is required', 422);
}

$blogId = (int)$data['blog_id'];

/* ================= FETCH CURRENT BLOG ================= */
$stmt = $db->prepare("
    SELECT approval_status, status, published_at
    FROM blogs
    WHERE id = :id
");
$stmt->execute(['id' => $blogId]);
$current = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$current) {
    Response::error('Blog not found', 404);
}

/* ================= BUSINESS RULE ================= */
/* Block invalid activation */
if (
    isset($data['status']) &&
    $data['status'] === 'Active' &&
    $current['approval_status'] !== 'Approved'
) {
    Response::error('Blog must be approved before activation', 422);
}

/* ================= BUILD UPDATE ================= */
$fields = [];
$params = [
    'id' => $blogId,
    'by' => $_SESSION['employee_id']
];

/* Allowed updatable fields */
$map = [
    'title'        => 'title',
    'slug'         => 'slug',
    'excerpt'      => 'excerpt',
    'content'      => 'content',
    'status'       => 'status',
    'published_at' => 'published_at'
];

foreach ($map as $key => $column) {
    if (array_key_exists($key, $data)) {
        $fields[] = "$column = :$key";
        $params[$key] = $data[$key];
    }
}

/* ================= PUBLISH LOGIC ================= */
/*
  Rules:
  - First time Active → set published_at + published_by
  - Manual published_at update → update published_by
*/
if (
    isset($data['status']) &&
    $data['status'] === 'Active' &&
    $current['status'] !== 'Active' &&
    empty($current['published_at'])
) {
    $fields[] = "published_at = NOW()";
    $fields[] = "published_by = :published_by";
    $params['published_by'] = $_SESSION['employee_id'];
}

if (array_key_exists('published_at', $data)) {
    $fields[] = "published_by = :published_by";
    $params['published_by'] = $_SESSION['employee_id'];
}

/* Nothing to update */
if (
    !$fields &&
    !isset($data['category_ids']) &&
    !isset($data['tag_ids'])
) {
    Response::error('No fields provided for update', 422);
}

/* ================= TRANSACTION ================= */
$db->beginTransaction();

try {

    /* CORE UPDATE */
    if ($fields) {
        $sql = "
            UPDATE blogs SET
                " . implode(', ', array_unique($fields)) . ",
                updated_by = :by,
                updated_at = NOW()
            WHERE id = :id
        ";
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
    }

    /* ================= CATEGORY SYNC ================= */
    if (isset($data['category_ids']) && is_array($data['category_ids'])) {

        $db->prepare("
            DELETE FROM blog_category_map
            WHERE blog_id = :id
        ")->execute(['id' => $blogId]);

        foreach ($data['category_ids'] as $cid) {
            $db->prepare("
                INSERT INTO blog_category_map (blog_id, category_id)
                VALUES (:b, :c)
            ")->execute([
                'b' => $blogId,
                'c' => (int)$cid
            ]);
        }
    }

    /* ================= TAG SYNC ================= */
    if (isset($data['tag_ids']) && is_array($data['tag_ids'])) {

        $db->prepare("
            DELETE FROM blog_tag_map
            WHERE blog_id = :id
        ")->execute(['id' => $blogId]);

        foreach ($data['tag_ids'] as $tid) {
            $db->prepare("
                INSERT INTO blog_tag_map (blog_id, tag_id)
                VALUES (:b, :t)
            ")->execute([
                'b' => $blogId,
                't' => (int)$tid
            ]);
        }
    }

    $db->commit();

} catch (Throwable $e) {
    $db->rollBack();
    Response::error('Failed to update blog', 500);
}

/* ================= SUCCESS ================= */
Response::success('Blog updated successfully');
