<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type, Authorization, SID');

// Database configuration
define('DB_HOST', 'localhost');
define('DB_NAME', 'wapaycom_update');
define('DB_USER', 'wapaycom_update');
define('DB_PASS', 'rtMO7!NLci#m');

try {
    $pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]);
    exit;
}

// Get SID from headers
function getSubscriberId() {
    // The SID header often comes through as HTTP_SID, but sometimes as just SID
    return isset($_SERVER['HTTP_SID']) ? (int)$_SERVER['HTTP_SID'] : (isset($_SERVER['SID']) ? (int)$_SERVER['SID'] : 1);
}

// Get cycle start date (last Saturday)
function getCycleStartDate() {
    $today = new DateTime();
    // 'w' is 0 (Sun) to 6 (Sat)
    // We want the previous Saturday.
    $dayOfWeek = $today->format('w');
    
    // Days to subtract to get to the *last* Saturday (or today if it is Saturday)
    // If it's Sat (6), daysBack is 0. If it's Sun (0), daysBack is 1. If it's Fri (5), daysBack is 6.
    $daysBack = ($dayOfWeek == 6) ? 0 : ($dayOfWeek + 1);
    
    $cycleStart = (clone $today)->modify("-$daysBack days");
    return $cycleStart->format('Y-m-d');
}

// Check if cycle should be reset (on Saturday at the start of the cycle)
function shouldResetCycle() {
    $today = new DateTime();
    // Day 6 is Saturday (start of Sat-Fri cycle)
    // The logic in your GET /history route is *re-initializing* the cycle
    // if it's Saturday, which seems to imply a Sat-Fri cycle where the reset happens on Sat.
    return $today->format('w') == 6; 
}

// Routing
$requestMethod = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uriSegments = explode('/', trim($uri, '/'));

// Remove everything before or including 'index.php'
if (($key = array_search('index.php', $uriSegments)) !== false) {
    $uriSegments = array_slice($uriSegments, $key + 1);
}

$sId = getSubscriberId();

if (!isset($uriSegments[0]) || $uriSegments[0] === '') {
    // POST / (check-in) or other root methods
    if ($requestMethod === 'POST') {
        $data = json_decode(file_get_contents('php://input'), true);
        $dayIndex = isset($data['dayIndex']) ? (int)$data['dayIndex'] : -1;

        if ($dayIndex < 0 || $dayIndex > 6) {
            http_response_code(400);
            echo json_encode(['error' => 'Invalid day index']);
            exit;
        }

        try {
            $cycleStartDate = getCycleStartDate();
            $today = new DateTime();
            // Your logic uses Sat=0, Sun=1, ..., Fri=6.
            // PHP's 'w' is Sun=0, Mon=1, ..., Sat=6.
            // (w + 1) % 7 maps Sun(0)->1, Sat(6)->0. This is an incorrect mapping for Sat=0, Fri=6.
            // Correct mapping for Sat=0, Sun=1, ..., Fri=6:
            $todayIndex = ($today->format('w') == 6) ? 0 : $today->format('w') + 1;

            if ($dayIndex !== $todayIndex) {
                http_response_code(400);
                echo json_encode(['error' => "Can only check in for today (expected day index: {$todayIndex})"]);
                exit;
            }

            // Check if user has a transaction today
            $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM transactions WHERE sId = ? AND DATE(`date`) = ?");
            $stmt->execute([$sId, $today->format('Y-m-d')]);
            $hasTransaction = $stmt->fetch(PDO::FETCH_ASSOC)['count'] > 0;

            if (!$hasTransaction) {
                http_response_code(403);
                echo json_encode(['error' => 'No transaction made today']);
                exit;
            }

            // Fetch current check-in history
            $stmt = $pdo->prepare("SELECT checked_days FROM checkin_history WHERE sId = ? AND cycle_start_date = ?");
            $stmt->execute([$sId, $cycleStartDate]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($result) {
                $checkedDays = json_decode($result['checked_days'], true);
                if ($checkedDays[$dayIndex]) {
                    http_response_code(400);
                    echo json_encode(['error' => 'Already checked in for this day']);
                    exit;
                }

                // Check streak for days before today (must be checked)
                // This logic correctly enforces a consecutive streak *up to* the current day.
                for ($i = 0; $i < $dayIndex; $i++) {
                    if (!$checkedDays[$i]) {
                        http_response_code(400);
                        echo json_encode(['error' => 'Streak broken. Cannot check in.']);
                        exit;
                    }
                }

                $checkedDays[$dayIndex] = true;

                // Determine the consecutive days for reward calculation
                $consecutiveDays = 0;
                for ($i = 0; $i < 7; $i++) {
                    if ($checkedDays[$i]) {
                        $consecutiveDays++;
                    } else {
                        break; // Streak breaks at first missed day
                    }
                }

                $rewardClaimed = false;
                if ($consecutiveDays == 7) {
                    // Insert voucher reward
                    $stmt = $pdo->prepare("INSERT INTO rewards (sId, voucher_amount, date_issued) VALUES (?, ?, ?)");
                    $stmt->execute([$sId, 200, $today->format('Y-m-d')]);
                    $rewardClaimed = true;
                }

                // Update check-in history
                $stmt = $pdo->prepare("UPDATE checkin_history SET checked_days = ? WHERE sId = ? AND cycle_start_date = ?");
                $stmt->execute([json_encode($checkedDays), $sId, $cycleStartDate]);

                echo json_encode([
                    'success' => true,
                    'checkedDays' => $checkedDays,
                    'rewardClaimed' => $rewardClaimed
                ]);
            } else {
                // If there's no check-in cycle record, it should be created and then check-in should proceed.
                // The current logic returns 404, which is a bit harsh. It should initialize the cycle.
                // However, to maintain the spirit of the original logic, we will keep the 404, 
                // but a better implementation would initialize the record here.
                http_response_code(404);
                echo json_encode(['error' => 'No check-in cycle found. Please GET /history first to initialize the cycle.']);
            }
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['error' => 'Check-in failed: ' . $e->getMessage()]);
        }
    } else {
        http_response_code(405); // Use 405 Method Not Allowed for non-POST to root
        echo json_encode(['error' => 'Method not allowed for root route. Only POST is supported.']);
    }
} elseif ($uriSegments[0] === 'history' && $requestMethod === 'GET') {
    // GET /history
    try {
        $cycleStartDate = getCycleStartDate();

        // Check if cycle should be reset (and reset it if it's the start of the cycle, Saturday)
        if (shouldResetCycle()) {
            // Delete old cycle (or just check if a new cycle is needed)
            // A more robust implementation might check if the *current* cycle_start_date 
            // is older than the calculated one, but for a Saturday reset:
            $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM checkin_history WHERE sId = ? AND cycle_start_date = ?");
            $stmt->execute([$sId, $cycleStartDate]);
            $isCycleInitialized = $stmt->fetch(PDO::FETCH_ASSOC)['count'] > 0;

            if (!$isCycleInitialized) {
                 // The reset logic in your original code seems to assume a DELETE + INSERT model on Saturday.
                 // This ensures that the history for the *new* Saturday is clean.
                 $checkedDays = [false, false, false, false, false, false, false];
                 $stmt = $pdo->prepare("INSERT INTO checkin_history (sId, cycle_start_date, checked_days) VALUES (?, ?, ?)");
                 $stmt->execute([$sId, $cycleStartDate, json_encode($checkedDays)]);
                 echo json_encode(['checkedDays' => $checkedDays]);
                 exit;
            }
        }
        
        $stmt = $pdo->prepare("SELECT checked_days FROM checkin_history WHERE sId = ? AND cycle_start_date = ?");
        $stmt->execute([$sId, $cycleStartDate]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($result) {
            echo json_encode(['checkedDays' => json_decode($result['checked_days'], true)]);
        } else {
            // Initialize new cycle if none is found for the current week
            $checkedDays = [false, false, false, false, false, false, false];
            $stmt = $pdo->prepare("INSERT INTO checkin_history (sId, cycle_start_date, checked_days) VALUES (?, ?, ?)");
            $stmt->execute([$sId, $cycleStartDate, json_encode($checkedDays)]);
            echo json_encode(['checkedDays' => $checkedDays]);
        }
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['error' => 'Failed to fetch history: ' . $e->getMessage()]);
    }
} elseif ($uriSegments[0] === 'verify' && $requestMethod === 'GET') {
    // GET /verify
    try {
        $today = (new DateTime())->format('Y-m-d');
        $stmt = $pdo->prepare("SELECT COUNT(*) as count FROM transactions WHERE sId = ? AND DATE(`date`) = ?");
        $stmt->execute([$sId, $today]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        echo json_encode(['hasTransaction' => $result['count'] > 0]);
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['error' => 'Failed to verify transaction: ' . $e->getMessage()]);
    }
} elseif ($uriSegments[0] === 'reset' && $requestMethod === 'POST') {
    // POST /reset
    // This is primarily for manual testing/debugging, as the cycle should reset automatically.
    try {
        $cycleStartDate = getCycleStartDate();
        
        // Use an UPSERT pattern to either update or insert (if it doesn't exist yet)
        $checkedDays = [false, false, false, false, false, false, false];
        $jsonCheckedDays = json_encode($checkedDays);
        
        // First try to delete the existing one for a clean reset, as your original logic did.
        $stmt = $pdo->prepare("DELETE FROM checkin_history WHERE sId = ? AND cycle_start_date = ?");
        $stmt->execute([$sId, $cycleStartDate]);
        
        // Then insert the fresh record
        $stmt = $pdo->prepare("INSERT INTO checkin_history (sId, cycle_start_date, checked_days) VALUES (?, ?, ?)");
        $stmt->execute([$sId, $cycleStartDate, $jsonCheckedDays]);
        
        echo json_encode(['success' => true, 'checkedDays' => $checkedDays]);
    } catch (PDOException $e) {
        http_response_code(500);
        echo json_encode(['error' => 'Failed to reset cycle: ' . $e->getMessage()]);
    }
} else {
    http_response_code(404);
    echo json_encode(['error' => 'Invalid route']);
}
?>