<?php
/**
 * Clients API Endpoint
 * RESTful API for client management
 */

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;
}

define('APP_RUNNING', true);
require_once '../db_connect.php';
require_once '../includes/auth.php';
require_once '../includes/client_access.php';

initSecureSession();

$response = ['success' => false, 'message' => '', 'data' => null];

// Authenticate and check role
$user = authenticateRequest($conn);
if (!$user) {
    $response['message'] = 'Authentication required';
    http_response_code(401);
    echo json_encode($response);
    exit;
}

// Only brokers and admins can access clients
if (!in_array($user['role'], ['broker', 'admin'])) {
    $response['message'] = 'Access denied. Broker or admin role required.';
    http_response_code(403);
    echo json_encode($response);
    exit;
}

$method = $_SERVER['REQUEST_METHOD'];
$client_id = isset($_GET['id']) ? intval($_GET['id']) : null;
$action = $_GET['action'] ?? '';

switch ($method) {
    case 'GET':
        if ($action === 'payment-status') {
            getClientPaymentStatus($conn, $client_id, $user, $response);
        } elseif ($client_id) {
            getClient($conn, $client_id, $user, $response);
        } else {
            getClients($conn, $user, $response);
        }
        break;

    case 'POST':
        if ($action === 'payment') {
            addPayment($conn, $client_id, $user, $response);
        } else {
            createClient($conn, $user, $response);
        }
        break;

    case 'PUT':
        if (!$client_id) {
            $response['message'] = 'Client ID required';
            http_response_code(400);
        } elseif ($action === 'status') {
            updateClientStatus($conn, $client_id, $user, $response);
        } else {
            updateClient($conn, $client_id, $user, $response);
        }
        break;

    case 'DELETE':
        if (!$client_id) {
            $response['message'] = 'Client ID required';
            http_response_code(400);
        } else {
            deleteClient($conn, $client_id, $user, $response);
        }
        break;

    default:
        $response['message'] = 'Method not allowed';
        http_response_code(405);
}

echo json_encode($response);
exit;

/**
 * Authenticate API request
 */
function authenticateRequest($conn) {
    $headers = getallheaders();
    $auth_header = $headers['Authorization'] ?? $headers['authorization'] ?? '';

    if (preg_match('/Bearer\s+(.*)$/i', $auth_header, $matches)) {
        $payload = verifyJWT($matches[1]);
        if ($payload) {
            $result = mysqli_query($conn, "SELECT * FROM users WHERE id = {$payload['user_id']} AND status = 'approved'");
            if ($user = mysqli_fetch_assoc($result)) {
                return $user;
            }
        }
    }

    if (isAuthenticated() && validateSession()) {
        $result = mysqli_query($conn, "SELECT * FROM users WHERE id = {$_SESSION['user_id']} AND status = 'approved'");
        if ($user = mysqli_fetch_assoc($result)) {
            return $user;
        }
    }

    return null;
}

/**
 * Get all clients
 */
function getClients($conn, $user, &$response) {
    $current_year = date('Y');

    // Build query based on role
    if ($user['role'] === 'admin') {
        $where = "1=1";
    } else {
        $where = "c.broker_id = {$user['id']}";
    }

    // Apply filters
    if (isset($_GET['status']) && $_GET['status']) {
        $status = mysqli_real_escape_string($conn, $_GET['status']);
        $where .= " AND c.access_status = '$status'";
    }

    if (isset($_GET['search']) && $_GET['search']) {
        $search = mysqli_real_escape_string($conn, $_GET['search']);
        $where .= " AND (c.full_name LIKE '%$search%' OR c.phone LIKE '%$search%' OR c.email LIKE '%$search%')";
    }

    $limit = isset($_GET['limit']) ? min(100, intval($_GET['limit'])) : 50;
    $offset = isset($_GET['offset']) ? intval($_GET['offset']) : 0;

    $sql = "SELECT c.*, u.full_name as broker_name,
                   (SELECT COUNT(*) FROM lands WHERE client_id = c.id) as land_count,
                   (SELECT MAX(payment_year) FROM client_payments WHERE client_id = c.id AND status = 'confirmed') as last_paid_year,
                   (SELECT SUM(amount) FROM client_payments WHERE client_id = c.id AND status = 'confirmed') as total_paid
            FROM clients c
            JOIN users u ON c.broker_id = u.id
            WHERE $where
            ORDER BY c.created_at DESC
            LIMIT $limit OFFSET $offset";

    $result = mysqli_query($conn, $sql);
    $clients = [];

    while ($client = mysqli_fetch_assoc($result)) {
        $client['is_paid_current_year'] = $client['last_paid_year'] >= $current_year;
        $clients[] = $client;
    }

    // Get total count
    $count_result = mysqli_query($conn, "SELECT COUNT(*) as total FROM clients c WHERE $where");
    $total = mysqli_fetch_assoc($count_result)['total'];

    $response['success'] = true;
    $response['data'] = [
        'clients' => $clients,
        'pagination' => [
            'total' => intval($total),
            'limit' => $limit,
            'offset' => $offset
        ]
    ];
}

/**
 * Get single client
 */
function getClient($conn, $client_id, $user, &$response) {
    // Check access
    $check = $user['role'] === 'admin'
        ? "c.id = $client_id"
        : "c.id = $client_id AND c.broker_id = {$user['id']}";

    $sql = "SELECT c.*, u.full_name as broker_name FROM clients c JOIN users u ON c.broker_id = u.id WHERE $check";
    $result = mysqli_query($conn, $sql);

    if (mysqli_num_rows($result) === 0) {
        $response['message'] = 'Client not found';
        http_response_code(404);
        return;
    }

    $client = mysqli_fetch_assoc($result);

    // Get payment status
    $client['payment_status'] = checkClientPaymentStatus($conn, $client_id);

    // Get lands
    $lands_result = mysqli_query($conn, "SELECT id, land_name, total_area, area_unit, created_at FROM lands WHERE client_id = $client_id");
    $client['lands'] = [];
    while ($land = mysqli_fetch_assoc($lands_result)) {
        $client['lands'][] = $land;
    }

    // Get payment history
    $payments_result = mysqli_query($conn, "SELECT * FROM client_payments WHERE client_id = $client_id ORDER BY payment_year DESC");
    $client['payments'] = [];
    while ($payment = mysqli_fetch_assoc($payments_result)) {
        $client['payments'][] = $payment;
    }

    $response['success'] = true;
    $response['data'] = $client;
}

/**
 * Get client payment status
 */
function getClientPaymentStatus($conn, $client_id, $user, &$response) {
    if (!$client_id) {
        $response['message'] = 'Client ID required';
        http_response_code(400);
        return;
    }

    // Check access
    $check = $user['role'] === 'admin'
        ? "id = $client_id"
        : "id = $client_id AND broker_id = {$user['id']}";

    if (mysqli_num_rows(mysqli_query($conn, "SELECT id FROM clients WHERE $check")) === 0) {
        $response['message'] = 'Client not found';
        http_response_code(404);
        return;
    }

    $status = checkClientPaymentStatus($conn, $client_id);

    $response['success'] = true;
    $response['data'] = $status;
}

/**
 * Create new client
 */
function createClient($conn, $user, &$response) {
    $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;

    $full_name = sanitizeInput($input['full_name'] ?? '');
    $phone = sanitizeInput($input['phone'] ?? '');

    if (empty($full_name) || empty($phone)) {
        $response['message'] = 'Full name and phone are required';
        http_response_code(400);
        return;
    }

    // Check for duplicate phone
    $phone_escaped = mysqli_real_escape_string($conn, $phone);
    if (mysqli_num_rows(mysqli_query($conn, "SELECT id FROM clients WHERE phone = '$phone_escaped' AND broker_id = {$user['id']}")) > 0) {
        $response['message'] = 'Client with this phone number already exists';
        http_response_code(400);
        return;
    }

    $email = mysqli_real_escape_string($conn, $input['email'] ?? '');
    $national_id = mysqli_real_escape_string($conn, $input['national_id'] ?? '');
    $address = mysqli_real_escape_string($conn, $input['address'] ?? '');
    $notes = mysqli_real_escape_string($conn, $input['notes'] ?? '');
    $full_name_escaped = mysqli_real_escape_string($conn, $full_name);

    $sql = "INSERT INTO clients (broker_id, full_name, email, phone, national_id, address, notes)
            VALUES ({$user['id']}, '$full_name_escaped', '$email', '$phone_escaped', '$national_id', '$address', '$notes')";

    if (mysqli_query($conn, $sql)) {
        $response['success'] = true;
        $response['message'] = 'Client created successfully';
        $response['data'] = ['id' => mysqli_insert_id($conn)];
        http_response_code(201);
    } else {
        $response['message'] = 'Failed to create client';
        http_response_code(500);
    }
}

/**
 * Update client
 */
function updateClient($conn, $client_id, $user, &$response) {
    // Check access
    $check = $user['role'] === 'admin' ? "id = $client_id" : "id = $client_id AND broker_id = {$user['id']}";
    if (mysqli_num_rows(mysqli_query($conn, "SELECT id FROM clients WHERE $check")) === 0) {
        $response['message'] = 'Client not found';
        http_response_code(404);
        return;
    }

    $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
    $updates = [];

    if (isset($input['full_name'])) {
        $updates[] = "full_name = '" . mysqli_real_escape_string($conn, $input['full_name']) . "'";
    }
    if (isset($input['email'])) {
        $updates[] = "email = '" . mysqli_real_escape_string($conn, $input['email']) . "'";
    }
    if (isset($input['phone'])) {
        $updates[] = "phone = '" . mysqli_real_escape_string($conn, $input['phone']) . "'";
    }
    if (isset($input['national_id'])) {
        $updates[] = "national_id = '" . mysqli_real_escape_string($conn, $input['national_id']) . "'";
    }
    if (isset($input['address'])) {
        $updates[] = "address = '" . mysqli_real_escape_string($conn, $input['address']) . "'";
    }
    if (isset($input['notes'])) {
        $updates[] = "notes = '" . mysqli_real_escape_string($conn, $input['notes']) . "'";
    }

    if (empty($updates)) {
        $response['message'] = 'No fields to update';
        http_response_code(400);
        return;
    }

    if (mysqli_query($conn, "UPDATE clients SET " . implode(', ', $updates) . " WHERE id = $client_id")) {
        $response['success'] = true;
        $response['message'] = 'Client updated successfully';
    } else {
        $response['message'] = 'Failed to update client';
        http_response_code(500);
    }
}

/**
 * Update client status (admin only)
 */
function updateClientStatus($conn, $client_id, $user, &$response) {
    if ($user['role'] !== 'admin') {
        $response['message'] = 'Admin access required';
        http_response_code(403);
        return;
    }

    $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
    $new_status = $input['status'] ?? '';

    if (!in_array($new_status, ['active', 'suspended', 'expired'])) {
        $response['message'] = 'Invalid status. Must be active, suspended, or expired.';
        http_response_code(400);
        return;
    }

    if (mysqli_query($conn, "UPDATE clients SET access_status = '$new_status' WHERE id = $client_id")) {
        $response['success'] = true;
        $response['message'] = 'Client status updated';
    } else {
        $response['message'] = 'Failed to update status';
        http_response_code(500);
    }
}

/**
 * Delete client
 */
function deleteClient($conn, $client_id, $user, &$response) {
    $check = $user['role'] === 'admin' ? "id = $client_id" : "id = $client_id AND broker_id = {$user['id']}";
    if (mysqli_num_rows(mysqli_query($conn, "SELECT id FROM clients WHERE $check")) === 0) {
        $response['message'] = 'Client not found';
        http_response_code(404);
        return;
    }

    // Check for lands
    $lands_count = mysqli_fetch_assoc(mysqli_query($conn, "SELECT COUNT(*) as cnt FROM lands WHERE client_id = $client_id"))['cnt'];
    if ($lands_count > 0) {
        $response['message'] = "Cannot delete client with $lands_count registered land(s)";
        http_response_code(400);
        return;
    }

    if (mysqli_query($conn, "DELETE FROM clients WHERE id = $client_id")) {
        $response['success'] = true;
        $response['message'] = 'Client deleted successfully';
    } else {
        $response['message'] = 'Failed to delete client';
        http_response_code(500);
    }
}

/**
 * Add payment for client
 */
function addPayment($conn, $client_id, $user, &$response) {
    if (!$client_id) {
        $response['message'] = 'Client ID required';
        http_response_code(400);
        return;
    }

    // Check access
    $check = $user['role'] === 'admin' ? "id = $client_id" : "id = $client_id AND broker_id = {$user['id']}";
    if (mysqli_num_rows(mysqli_query($conn, "SELECT id FROM clients WHERE $check")) === 0) {
        $response['message'] = 'Client not found';
        http_response_code(404);
        return;
    }

    $input = json_decode(file_get_contents('php://input'), true) ?: $_POST;

    $amount = floatval($input['amount'] ?? 0);
    $payment_year = intval($input['payment_year'] ?? date('Y'));
    $payment_date = mysqli_real_escape_string($conn, $input['payment_date'] ?? date('Y-m-d'));
    $payment_method = mysqli_real_escape_string($conn, $input['payment_method'] ?? 'cash');
    $reference_number = mysqli_real_escape_string($conn, $input['reference_number'] ?? '');
    $notes = mysqli_real_escape_string($conn, $input['notes'] ?? '');

    if ($amount <= 0) {
        $response['message'] = 'Amount must be greater than zero';
        http_response_code(400);
        return;
    }

    // Check for existing payment
    if (mysqli_num_rows(mysqli_query($conn, "SELECT id FROM client_payments WHERE client_id = $client_id AND payment_year = $payment_year AND status = 'confirmed'")) > 0) {
        $response['message'] = "Payment for year $payment_year already exists";
        http_response_code(400);
        return;
    }

    $status = $user['role'] === 'admin' ? 'confirmed' : 'pending';
    $confirmed_by = $user['role'] === 'admin' ? $user['id'] : 'NULL';

    $sql = "INSERT INTO client_payments (client_id, amount, payment_year, payment_date, payment_method, reference_number, notes, status, recorded_by, confirmed_by)
            VALUES ($client_id, $amount, $payment_year, '$payment_date', '$payment_method', '$reference_number', '$notes', '$status', {$user['id']}, $confirmed_by)";

    if (mysqli_query($conn, $sql)) {
        // Update client status if payment confirmed
        if ($status === 'confirmed' && $payment_year >= date('Y')) {
            mysqli_query($conn, "UPDATE clients SET access_status = 'active' WHERE id = $client_id");
        }

        $response['success'] = true;
        $response['message'] = 'Payment recorded successfully';
        $response['data'] = [
            'id' => mysqli_insert_id($conn),
            'status' => $status
        ];
        http_response_code(201);
    } else {
        $response['message'] = 'Failed to record payment';
        http_response_code(500);
    }
}
?>
