<?php
/**
 * Opel Lifts Attendance - Main API Router
 * PHP 8.1+ / PDO MySQL
 */

require_once __DIR__ . '/config/database.php';

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

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

date_default_timezone_set('Asia/Kolkata');

$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
$input = json_decode(file_get_contents('php://input'), true) ?? [];

// JWT Helper Functions
function jwt_encode(array $payload): string {
    $header = base64url_encode(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
    $payload['exp'] = time() + 86400;
    $body = base64url_encode(json_encode($payload));
    $signature = base64url_encode(hash_hmac('sha256', "$header.$body", Config::get('JWT_SECRET'), true));
    return "$header.$body.$signature";
}

function jwt_decode(string $token): ?array {
    $parts = explode('.', $token);
    if (count($parts) !== 3) return null;
    $expected = base64url_encode(hash_hmac('sha256', "$parts[0].$parts[1]", Config::get('JWT_SECRET'), true));
    if (!hash_equals($expected, $parts[2])) return null;
    $payload = json_decode(base64url_decode($parts[1]), true);
    if ($payload['exp'] < time()) return null;
    return $payload;
}

function base64url_encode($data): string {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function base64url_decode($data): string {
    return base64_decode(strtr($data, '-_', '+/'));
}

function get_current_user_from_token(): ?array {
    $auth = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
    if (!str_starts_with($auth, 'Bearer ')) return null;
    $payload = jwt_decode(substr($auth, 7));
    if (!$payload) return null;
    $db = Database::getConnection();
    $stmt = $db->prepare('SELECT employee_id, name, role, is_active FROM employees WHERE employee_id = ?');
    $stmt->execute([$payload['employee_id']]);
    return $stmt->fetch() ?: null;
}

function require_auth(): array {
    $user = get_current_user_from_token();
    if (!$user) { http_response_code(401); echo json_encode(['detail' => 'Unauthorized']); exit; }
    return $user;
}

function require_admin(): array {
    $user = require_auth();
    if ($user['role'] !== 'admin') { http_response_code(403); echo json_encode(['detail' => 'Admin required']); exit; }
    return $user;
}

function push_to_google_sheets(array $data): bool {
    $url = Config::get('GOOGLE_SHEETS_URL');
    if (!$url) return false;
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 15,
    ]);
    curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $code === 200;
}

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

// --- ROUTES ---
$db = Database::getConnection();

// POST /api/auth/login
if ($uri === '/api/auth/login' && $method === 'POST') {
    $stmt = $db->prepare('SELECT * FROM employees WHERE employee_id = ?');
    $stmt->execute([$input['employee_id'] ?? '']);
    $emp = $stmt->fetch();
    if (!$emp || !password_verify($input['password'] ?? '', $emp['password_hash'])) {
        respond(['detail' => 'Invalid Employee ID or password'], 401);
    }
    if (!$emp['is_active']) respond(['detail' => 'Account is deactivated'], 403);
    $token = jwt_encode(['employee_id' => $emp['employee_id'], 'role' => $emp['role']]);
    respond(['token' => $token, 'employee' => [
        'employee_id' => $emp['employee_id'], 'name' => $emp['name'], 'role' => $emp['role']
    ]]);
}

// POST /api/auth/forgot-password
if ($uri === '/api/auth/forgot-password' && $method === 'POST') {
    $stmt = $db->prepare('SELECT employee_id FROM employees WHERE employee_id = ?');
    $stmt->execute([$input['employee_id'] ?? '']);
    if (!$stmt->fetch()) respond(['detail' => 'Employee ID not found'], 404);
    $token = bin2hex(random_bytes(16));
    $expiry = date('Y-m-d H:i:s', strtotime('+1 hour'));
    $db->prepare('UPDATE employees SET reset_token = ?, reset_token_expiry = ? WHERE employee_id = ?')
       ->execute([$token, $expiry, $input['employee_id']]);
    respond(['message' => 'Password reset initiated', 'reset_token' => $token]);
}

// POST /api/auth/reset-password
if ($uri === '/api/auth/reset-password' && $method === 'POST') {
    $stmt = $db->prepare('SELECT reset_token FROM employees WHERE employee_id = ?');
    $stmt->execute([$input['employee_id'] ?? '']);
    $emp = $stmt->fetch();
    if (!$emp || $emp['reset_token'] !== ($input['reset_token'] ?? '')) {
        respond(['detail' => 'Invalid reset token'], 400);
    }
    $hash = password_hash($input['new_password'], PASSWORD_BCRYPT);
    $db->prepare('UPDATE employees SET password_hash = ?, reset_token = NULL, reset_token_expiry = NULL WHERE employee_id = ?')
       ->execute([$hash, $input['employee_id']]);
    respond(['message' => 'Password reset successful']);
}

// GET /api/attendance/status
if ($uri === '/api/attendance/status' && $method === 'GET') {
    $user = require_auth();
    $today = date('Y-m-d');
    $stmt = $db->prepare('SELECT action, time, location_url FROM attendance WHERE employee_id = ? AND date = ?');
    $stmt->execute([$user['employee_id'], $today]);
    $records = $stmt->fetchAll();
    $login = array_filter($records, fn($r) => $r['action'] === 'Login');
    $logout = array_filter($records, fn($r) => $r['action'] === 'Logout');
    $loginRec = reset($login) ?: null;
    $logoutRec = reset($logout) ?: null;
    respond([
        'date' => $today, 'has_login' => !empty($login), 'has_logout' => !empty($logout),
        'can_login' => empty($login), 'can_logout' => !empty($login) && empty($logout),
        'login_time' => $loginRec['time'] ?? null, 'logout_time' => $logoutRec['time'] ?? null,
        'login_location' => $loginRec['location_url'] ?? null, 'logout_location' => $logoutRec['location_url'] ?? null,
    ]);
}

// POST /api/attendance/login
if ($uri === '/api/attendance/login' && $method === 'POST') {
    $user = require_auth();
    $today = date('Y-m-d');
    $stmt = $db->prepare('SELECT id FROM attendance WHERE employee_id = ? AND date = ? AND action = "Login"');
    $stmt->execute([$user['employee_id'], $today]);
    if ($stmt->fetch()) respond(['detail' => 'Already logged in today'], 400);
    $time = date('h:i:s A');
    $loc = "https://maps.google.com/?q={$input['latitude']},{$input['longitude']}";
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    $db->prepare('INSERT INTO attendance (employee_id, name, date, action, time, timestamp, latitude, longitude, location_url, ip_address, is_auto_logout) VALUES (?, ?, ?, "Login", ?, NOW(), ?, ?, ?, ?, 0)')
       ->execute([$user['employee_id'], $user['name'], $today, $time, $input['latitude'], $input['longitude'], $loc, $ip]);
    push_to_google_sheets([
        'date' => $today, 'employee_id' => $user['employee_id'], 'name' => $user['name'],
        'action' => 'Login', 'time' => $time, 'location_url' => $loc,
        'latitude' => (string)$input['latitude'], 'longitude' => (string)$input['longitude'],
        'ip_address' => $ip, 'auto_logout' => 'No'
    ]);
    respond(['message' => 'Login marked successfully', 'time' => $time, 'location_url' => $loc]);
}

// POST /api/attendance/logout
if ($uri === '/api/attendance/logout' && $method === 'POST') {
    $user = require_auth();
    $today = date('Y-m-d');
    $stmt = $db->prepare('SELECT id FROM attendance WHERE employee_id = ? AND date = ? AND action = "Login"');
    $stmt->execute([$user['employee_id'], $today]);
    if (!$stmt->fetch()) respond(['detail' => 'Must login first'], 400);
    $stmt = $db->prepare('SELECT id FROM attendance WHERE employee_id = ? AND date = ? AND action = "Logout"');
    $stmt->execute([$user['employee_id'], $today]);
    if ($stmt->fetch()) respond(['detail' => 'Already logged out today'], 400);
    $time = date('h:i:s A');
    $loc = "https://maps.google.com/?q={$input['latitude']},{$input['longitude']}";
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    $db->prepare('INSERT INTO attendance (employee_id, name, date, action, time, timestamp, latitude, longitude, location_url, ip_address, is_auto_logout) VALUES (?, ?, ?, "Logout", ?, NOW(), ?, ?, ?, ?, 0)')
       ->execute([$user['employee_id'], $user['name'], $today, $time, $input['latitude'], $input['longitude'], $loc, $ip]);
    push_to_google_sheets([
        'date' => $today, 'employee_id' => $user['employee_id'], 'name' => $user['name'],
        'action' => 'Logout', 'time' => $time, 'location_url' => $loc,
        'latitude' => (string)$input['latitude'], 'longitude' => (string)$input['longitude'],
        'ip_address' => $ip, 'auto_logout' => 'No'
    ]);
    respond(['message' => 'Logout marked successfully', 'time' => $time, 'location_url' => $loc]);
}

// GET /api/attendance/history
if ($uri === '/api/attendance/history' && $method === 'GET') {
    $user = require_auth();
    $days = (int)($_GET['days'] ?? 30);
    $stmt = $db->prepare('SELECT employee_id, name, date, action, time, location_url, is_auto_logout FROM attendance WHERE employee_id = ? ORDER BY timestamp DESC LIMIT ?');
    $stmt->execute([$user['employee_id'], $days * 2]);
    respond(['records' => $stmt->fetchAll()]);
}

// POST /api/attendance/auto-logout (cron endpoint)
if ($uri === '/api/attendance/auto-logout' && $method === 'POST') {
    $today = date('Y-m-d');
    $stmt = $db->prepare('SELECT DISTINCT a.employee_id, a.name, a.latitude, a.longitude, a.location_url FROM attendance a WHERE a.date = ? AND a.action = "Login" AND a.employee_id NOT IN (SELECT employee_id FROM attendance WHERE date = ? AND action = "Logout")');
    $stmt->execute([$today, $today]);
    $pending = $stmt->fetchAll();
    $count = 0;
    foreach ($pending as $rec) {
        $db->prepare('INSERT INTO attendance (employee_id, name, date, action, time, timestamp, latitude, longitude, location_url, ip_address, is_auto_logout) VALUES (?, ?, ?, "Logout", "11:59:00 PM", NOW(), ?, ?, ?, "auto-system", 1)')
           ->execute([$rec['employee_id'], $rec['name'], $today, $rec['latitude'], $rec['longitude'], $rec['location_url']]);
        push_to_google_sheets([
            'date' => $today, 'employee_id' => $rec['employee_id'], 'name' => $rec['name'],
            'action' => 'Logout', 'time' => '11:59:00 PM', 'location_url' => $rec['location_url'] ?? '',
            'latitude' => (string)($rec['latitude'] ?? 0), 'longitude' => (string)($rec['longitude'] ?? 0),
            'ip_address' => 'auto-system', 'auto_logout' => 'Yes'
        ]);
        $count++;
    }
    respond(['message' => "Auto logout completed for $count employees"]);
}

// GET /api/admin/employees
if ($uri === '/api/admin/employees' && $method === 'GET') {
    require_admin();
    $stmt = $db->query('SELECT employee_id, name, role, is_active, created_at FROM employees ORDER BY created_at');
    respond(['employees' => $stmt->fetchAll()]);
}

// POST /api/admin/employees
if ($uri === '/api/admin/employees' && $method === 'POST') {
    require_admin();
    $stmt = $db->prepare('SELECT id FROM employees WHERE employee_id = ?');
    $stmt->execute([$input['employee_id'] ?? '']);
    if ($stmt->fetch()) respond(['detail' => 'Employee ID already exists'], 400);
    $hash = password_hash($input['password'], PASSWORD_BCRYPT);
    $db->prepare('INSERT INTO employees (employee_id, name, password_hash, role, is_active) VALUES (?, ?, ?, ?, 1)')
       ->execute([$input['employee_id'], $input['name'], $hash, $input['role'] ?? 'employee']);
    respond(['message' => 'Employee created', 'employee_id' => $input['employee_id']]);
}

// PUT /api/admin/employees/{id}
if (preg_match('#^/api/admin/employees/(.+)$#', $uri, $m) && $method === 'PUT') {
    require_admin();
    $sets = []; $params = [];
    foreach (['name', 'role', 'is_active'] as $field) {
        if (isset($input[$field])) { $sets[] = "$field = ?"; $params[] = $input[$field]; }
    }
    if (empty($sets)) respond(['detail' => 'No fields to update'], 400);
    $params[] = $m[1];
    $db->prepare('UPDATE employees SET ' . implode(', ', $sets) . ' WHERE employee_id = ?')->execute($params);
    respond(['message' => 'Employee updated']);
}

// DELETE /api/admin/employees/{id}
if (preg_match('#^/api/admin/employees/(.+)$#', $uri, $m) && $method === 'DELETE') {
    require_admin();
    if ($m[1] === 'ADMIN001') respond(['detail' => 'Cannot delete primary admin'], 400);
    $db->prepare('DELETE FROM employees WHERE employee_id = ?')->execute([$m[1]]);
    respond(['message' => 'Employee deleted']);
}

// POST /api/admin/change-password
if ($uri === '/api/admin/change-password' && $method === 'POST') {
    require_admin();
    $hash = password_hash($input['new_password'], PASSWORD_BCRYPT);
    $db->prepare('UPDATE employees SET password_hash = ? WHERE employee_id = ?')
       ->execute([$hash, $input['employee_id']]);
    respond(['message' => 'Password changed successfully']);
}

// GET /api/admin/attendance
if ($uri === '/api/admin/attendance' && $method === 'GET') {
    require_admin();
    $date = $_GET['date'] ?? date('Y-m-d');
    $stmt = $db->prepare('SELECT employee_id, name, date, action, time, is_auto_logout FROM attendance WHERE date = ? ORDER BY timestamp DESC');
    $stmt->execute([$date]);
    respond(['records' => $stmt->fetchAll(), 'date' => $date]);
}

// GET /api/health
if ($uri === '/api/health' && $method === 'GET') {
    respond(['status' => 'ok', 'timestamp' => date('c')]);
}

respond(['detail' => 'Not found'], 404);
