<?php
require_once __DIR__ . '/_admin_guard.php';

function relations_json_response($data, int $code = 200): void
{
    http_response_code($code);
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function relations_read_json_input(): ?array
{
    $raw = file_get_contents('php://input');
    if ($raw === false || trim($raw) === '') {
        return null;
    }

    $decoded = json_decode($raw, true);
    return is_array($decoded) ? $decoded : null;
}

function relations_to_nullable_string($value, int $maxLength = 500): ?string
{
    if ($value === null) {
        return null;
    }

    $str = trim((string) $value);
    if ($str === '') {
        return null;
    }

    return mb_substr($str, 0, $maxLength);
}

function relations_to_int($value, int $default = 0): int
{
    if ($value === null || $value === '') {
        return $default;
    }

    return max(0, (int) $value);
}

function relations_to_bool_int($value, int $default = 1): int
{
    if ($value === null || $value === '') {
        return $default;
    }

    if (is_bool($value)) {
        return $value ? 1 : 0;
    }

    $normalized = strtolower(trim((string) $value));
    $truthy = ['1', 'true', 'on', 'yes'];
    return in_array($normalized, $truthy, true) ? 1 : 0;
}

function relations_extract_logo_path(array $input): ?string
{
    if (array_key_exists('logo_path', $input)) {
        return relations_to_nullable_string($input['logo_path'], 500);
    }

    if (array_key_exists('logo', $input)) {
        return relations_to_nullable_string($input['logo'], 500);
    }

    if (array_key_exists('img', $input)) {
        return relations_to_nullable_string($input['img'], 500);
    }

    return null;
}

function relations_handle_get(PDO $pdo, string $table): void
{
    $includeInactive = isset($_GET['include_inactive']) && (string) $_GET['include_inactive'] === '1';

    if (isset($_GET['id'])) {
        $id = (int) $_GET['id'];
        if ($id <= 0) {
            relations_json_response(['success' => false, 'message' => 'Invalid id'], 400);
        }

        $sql = "SELECT * FROM {$table} WHERE id = :id";
        if (!$includeInactive) {
            $sql .= ' AND is_active = 1';
        }
        $sql .= ' LIMIT 1';

        $stmt = $pdo->prepare($sql);
        $stmt->execute([':id' => $id]);
        $row = $stmt->fetch();

        if (!$row) {
            relations_json_response(['success' => false, 'message' => 'Not found'], 404);
        }

        relations_json_response($row);
    }

    $sql = "SELECT * FROM {$table}";
    if (!$includeInactive) {
        $sql .= ' WHERE is_active = 1';
    }
    $sql .= ' ORDER BY display_order ASC, created_at DESC';

    $stmt = $pdo->query($sql);
    $rows = $stmt->fetchAll();
    relations_json_response($rows);
}

function relations_handle_post(PDO $pdo, string $table, string $scope): void
{
    api_guard_require_admin_with_rate_limit($scope);

    $input = relations_read_json_input();
    if (!$input) {
        relations_json_response(['success' => false, 'message' => 'Invalid JSON'], 400);
    }

    $name = relations_to_nullable_string($input['name'] ?? null, 255);
    if ($name === null) {
        relations_json_response(['success' => false, 'message' => 'Name is required'], 400);
    }

    $url = relations_to_nullable_string($input['url'] ?? null, 500);
    $logoPath = relations_extract_logo_path($input);
    $displayOrder = relations_to_int($input['display_order'] ?? null, 0);
    $isActive = relations_to_bool_int($input['is_active'] ?? null, 1);

    $stmt = $pdo->prepare(
        "INSERT INTO {$table} (name, url, logo_path, display_order, is_active) VALUES (:name, :url, :logo_path, :display_order, :is_active)"
    );

    $stmt->execute([
        ':name' => $name,
        ':url' => $url,
        ':logo_path' => $logoPath,
        ':display_order' => $displayOrder,
        ':is_active' => $isActive,
    ]);

    relations_json_response([
        'success' => true,
        'id' => (int) $pdo->lastInsertId(),
    ], 201);
}

function relations_handle_put(PDO $pdo, string $table, string $scope): void
{
    api_guard_require_admin_with_rate_limit($scope);

    $input = relations_read_json_input();
    if (!$input || !isset($input['id'])) {
        relations_json_response(['success' => false, 'message' => 'Missing id or invalid JSON'], 400);
    }

    $id = (int) $input['id'];
    if ($id <= 0) {
        relations_json_response(['success' => false, 'message' => 'Invalid id'], 400);
    }

    $updates = [];
    $params = [':id' => $id];

    if (array_key_exists('name', $input)) {
        $name = relations_to_nullable_string($input['name'], 255);
        if ($name === null) {
            relations_json_response(['success' => false, 'message' => 'Name cannot be empty'], 400);
        }
        $updates[] = 'name = :name';
        $params[':name'] = $name;
    }

    if (array_key_exists('url', $input)) {
        $updates[] = 'url = :url';
        $params[':url'] = relations_to_nullable_string($input['url'], 500);
    }

    if (array_key_exists('logo_path', $input) || array_key_exists('logo', $input) || array_key_exists('img', $input)) {
        $updates[] = 'logo_path = :logo_path';
        $params[':logo_path'] = relations_extract_logo_path($input);
    }

    if (array_key_exists('display_order', $input)) {
        $updates[] = 'display_order = :display_order';
        $params[':display_order'] = relations_to_int($input['display_order'], 0);
    }

    if (array_key_exists('is_active', $input)) {
        $updates[] = 'is_active = :is_active';
        $params[':is_active'] = relations_to_bool_int($input['is_active'], 1);
    }

    if (empty($updates)) {
        relations_json_response(['success' => false, 'message' => 'No fields to update'], 400);
    }

    $sql = "UPDATE {$table} SET " . implode(', ', $updates) . ' WHERE id = :id';
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);

    relations_json_response(['success' => true]);
}

/**
 * Deletes a logo file that lives inside our uploads directory.
 * Only removes files under uploads/relations/ or uploads/ — never arbitrary paths.
 */
function relations_delete_logo_file(string $logoPath): void
{
    $logoPath = trim($logoPath);
    if ($logoPath === '') return;

    $filename = basename(parse_url($logoPath, PHP_URL_PATH) ?? '');
    if ($filename === '' || $filename === '.') return;

    $candidates = [
        __DIR__ . '/../uploads/relations/' . $filename,
        __DIR__ . '/../uploads/' . $filename,
    ];

    $relDir = realpath(__DIR__ . '/../uploads/relations');
    $upDir  = realpath(__DIR__ . '/../uploads');

    foreach ($candidates as $candidate) {
        $real = realpath($candidate);
        if ($real === false) continue;

        // Confirm the resolved path is still inside our uploads tree
        $inRelDir = $relDir !== false && strpos($real, $relDir . DIRECTORY_SEPARATOR) === 0;
        $inUpDir  = $upDir  !== false && strpos($real, $upDir  . DIRECTORY_SEPARATOR) === 0;

        if ($inRelDir || $inUpDir) {
            @unlink($real);
            return;
        }
    }
}

function relations_handle_delete(PDO $pdo, string $table, string $scope): void
{
    api_guard_require_admin_with_rate_limit($scope);

    $id = null;
    if (isset($_GET['id'])) {
        $id = (int) $_GET['id'];
    } else {
        $input = relations_read_json_input();
        if (is_array($input) && isset($input['id'])) {
            $id = (int) $input['id'];
        }
    }

    if (!$id || $id <= 0) {
        relations_json_response(['success' => false, 'message' => 'Missing id'], 400);
    }

    // Fetch logo_path before deleting so we can clean up the file
    $fetchStmt = $pdo->prepare("SELECT logo_path FROM {$table} WHERE id = :id LIMIT 1");
    $fetchStmt->execute([':id' => $id]);
    $row = $fetchStmt->fetch();

    if (!$row) {
        relations_json_response(['success' => false, 'message' => 'Not found'], 404);
    }

    $stmt = $pdo->prepare("DELETE FROM {$table} WHERE id = :id");
    $stmt->execute([':id' => $id]);

    if ($stmt->rowCount() === 0) {
        relations_json_response(['success' => false, 'message' => 'Not found'], 404);
    }

    // Delete logo file after successful DB delete
    if (!empty($row['logo_path'])) {
        relations_delete_logo_file($row['logo_path']);
    }

    relations_json_response(['success' => true]);
}

function relations_handle_request(PDO $pdo, string $table, string $scope): void
{
    if (!preg_match('/^[a-z_]+$/', $table)) {
        relations_json_response(['success' => false, 'message' => 'Invalid table configuration'], 500);
    }

    $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

    try {
        if ($method === 'GET') {
            relations_handle_get($pdo, $table);
        }

        if ($method === 'POST') {
            relations_handle_post($pdo, $table, $scope);
        }

        if ($method === 'PUT') {
            relations_handle_put($pdo, $table, $scope);
        }

        if ($method === 'DELETE') {
            relations_handle_delete($pdo, $table, $scope);
        }

        relations_json_response(['success' => false, 'message' => 'Method not allowed'], 405);
    } catch (Exception $e) {
        relations_json_response([
            'success' => false,
            'message' => $e->getMessage(),
        ], 500);
    }
}
