<?php
// syncDiscounts.php

// DEBUG: show PHP errors (remove or lower in production)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

header("Content-Type: application/json");
header("Access-Control-Allow-Origin", "*");
header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
header("Access-Control-Allow-Headers", "Content-Type");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    echo json_encode(["status" => "ok", "message" => "OPTIONS"]);
    exit;
}

// Include config.php which creates $pdo
require_once __DIR__ . '/../../config.php';

$method = $_SERVER['REQUEST_METHOD'];

try {
    if ($method === 'GET') {
        // PULL: send discounts to desktop
        pullDiscounts($pdo);
        exit;
    }

    if ($method === 'POST') {
        // PUSH: receive discounts from desktop
        $raw  = file_get_contents('php://input');
        $data = json_decode($raw, true);

        if (!is_array($data)) {
            http_response_code(400);
            echo json_encode(["error" => "Invalid JSON payload"]);
            exit;
        }

        syncDiscounts($pdo, $data);
        exit;
    }

    http_response_code(405);
    echo json_encode([
        "error"  => "Method not allowed",
        "method" => $method
    ]);
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode([
        "error"   => "Server error",
        "details" => $e->getMessage()
    ]);
}

/**
 * GET: return all discounts for desktop sync.
 * Must match DiscountSyncDto:
 *  Id, Name, Code, Type, PercentageValue, AmountValue,
 *  StartDate, EndDate, MaxUses, TimesUsed, IsActive, LastModified
 */
function pullDiscounts(PDO $pdo)
{
    $stmt = $pdo->query("
        SELECT
            Id,
            Name,
            Code,
            Type,
            PercentageValue,
            AmountValue,
            StartDate,
            EndDate,
            MaxUses,
            TimesUsed,
            IsActive,
            LastModified
        FROM Discounts
        ORDER BY Id
    ");
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    echo json_encode($rows);
}

/**
 * POST: receive discounts from desktop.
 *
 * Uses Discounts.LastModified as conflict resolver:
 *  - If desktop LastModified (converted from ISO) is newer than server, update.
 *  - If server is newer or equal, skip.
 */
function syncDiscounts(PDO $pdo, array $discounts)
{
    $pdo->beginTransaction();

    // Get current LastModified for existing discount
    $select = $pdo->prepare("
        SELECT LastModified
        FROM Discounts
        WHERE Id = :Id
    ");

    // Insert new discount
    $insert = $pdo->prepare("
        INSERT INTO Discounts
        (Id, Name, Code, Type,
         PercentageValue, AmountValue,
         StartDate, EndDate,
         MaxUses, TimesUsed, IsActive,
         CreatedByUserId, CreatedAt, LastModified)
        VALUES
        (:Id, :Name, :Code, :Type,
         :PercentageValue, :AmountValue,
         :StartDate, :EndDate,
         :MaxUses, :TimesUsed, :IsActive,
         :CreatedByUserId, :CreatedAt, :LastModified)
    ");

    // Update existing discount if desktop is newer
    $update = $pdo->prepare("
        UPDATE Discounts
        SET Name            = :Name,
            Code            = :Code,
            Type            = :Type,
            PercentageValue = :PercentageValue,
            AmountValue     = :AmountValue,
            StartDate       = :StartDate,
            EndDate         = :EndDate,
            MaxUses         = :MaxUses,
            TimesUsed       = :TimesUsed,
            IsActive        = :IsActive,
            CreatedByUserId = :CreatedByUserId,
            CreatedAt       = :CreatedAt,
            LastModified    = :LastModified
        WHERE Id = :Id
    ");

    $count = 0;

    foreach ($discounts as $d) {
        $id = isset($d['Id']) ? (int)$d['Id'] : null;
        if ($id === null) {
            continue;
        }

        $name   = $d['Name'] ?? '';
        $code   = $d['Code'] ?? '';
        $type   = $d['Type'] ?? '';

        $perc   = isset($d['PercentageValue']) && $d['PercentageValue'] !== ''
            ? (float)$d['PercentageValue']
            : null;
        $amount = isset($d['AmountValue']) && $d['AmountValue'] !== ''
            ? (float)$d['AmountValue']
            : null;

        $start  = $d['StartDate'] ?? null;
        $end    = $d['EndDate'] ?? null;
        $max    = isset($d['MaxUses']) ? (int)$d['MaxUses'] : null;
        $times  = isset($d['TimesUsed']) ? (int)$d['TimesUsed'] : 0;
        $active = !empty($d['IsActive']) ? 1 : 0;

        // Optional: CreatedByUserId and CreatedAt (desktop may not send them)
        $createdBy = isset($d['CreatedByUserId']) ? (int)$d['CreatedByUserId'] : null;
        $createdAt = $d['CreatedAt'] ?? date('Y-m-d H:i:s');

        // Incoming LastModified from desktop (ISO text)
        $incomingLast = $d['LastModified'] ?? null;
        if ($incomingLast === null) {
            $incomingLast = gmdate('Y-m-d\TH:i:s\Z');
        }
        $incomingTime = strtotime($incomingLast);
        if ($incomingTime === false) {
            $incomingTime = time();
        }
        $incomingLastMysql = gmdate('Y-m-d H:i:s', $incomingTime);

        // Check existing row
        $select->execute([':Id' => $id]);
        $row = $select->fetch(PDO::FETCH_ASSOC);

        if (!$row) {
            // New row → INSERT
            $insert->execute([
                ':Id'              => $id,
                ':Name'            => $name,
                ':Code'            => $code,
                ':Type'            => $type,
                ':PercentageValue' => $perc,
                ':AmountValue'     => $amount,
                ':StartDate'       => $start,
                ':EndDate'         => $end,
                ':MaxUses'         => $max,
                ':TimesUsed'       => $times,
                ':IsActive'        => $active,
                ':CreatedByUserId' => $createdBy,
                ':CreatedAt'       => $createdAt,
                ':LastModified'    => $incomingLastMysql,
            ]);

            $count++;
            continue;
        }

        // Existing row: compare LastModified
        $serverLast = $row['LastModified'];
        if (!empty($serverLast)) {
            $serverTime = strtotime($serverLast);
            if ($serverTime !== false && $incomingTime <= $serverTime) {
                // Server newer or equal → skip
                continue;
            }
        }

        // Desktop newer → UPDATE
        $update->execute([
            ':Id'              => $id,
            ':Name'            => $name,
            ':Code'            => $code,
            ':Type'            => $type,
            ':PercentageValue' => $perc,
            ':AmountValue'     => $amount,
            ':StartDate'       => $start,
            ':EndDate'         => $end,
            ':MaxUses'         => $max,
            ':TimesUsed'       => $times,
            ':IsActive'        => $active,
            ':CreatedByUserId' => $createdBy,
            ':CreatedAt'       => $createdAt,
            ':LastModified'    => $incomingLastMysql,
        ]);

        $count++;
    }

    $pdo->commit();

    echo json_encode([
        "status" => "ok",
        "entity" => "discounts",
        "synced" => $count
    ]);
}
