<?php
/**
 * Public quote route handlers.
 *
 * These endpoints do not require authentication. They allow prospects
 * to create, view, update, and submit quotes using an access token.
 */

// Deny direct access
if (basename($_SERVER['SCRIPT_FILENAME'] ?? '') === basename(__FILE__)) {
    http_response_code(403);
    exit('Direct access denied.');
}

require_once __DIR__ . '/../helpers.php';
require_once __DIR__ . '/../db.php';
require_once __DIR__ . '/../services/quote_service.php';
require_once __DIR__ . '/../services/email_service.php';

/**
 * POST /quotes
 *
 * Create a new quote draft. Returns the quote ID, access token, status, and
 * a success message. HTTP 201 on success.
 */
function handle_create_quote(): void
{
    $data = get_json_body();
    $ip   = get_client_ip();
    $ua   = get_user_agent();
    $db   = get_db();

    // Validate employee_count if provided
    if (isset($data['employee_count'])) {
        $data['employee_count'] = (int)$data['employee_count'];
        if ($data['employee_count'] < 1) {
            error_response('employee_count must be >= 1', 422);
        }
    }

    $quote = create_quote($db, $data, $ip, $ua);

    json_response([
        'id'           => $quote['id'],
        'access_token' => $quote['access_token'],
        'status'       => $quote['status'],
        'message'      => 'Quote created successfully. Use the access_token to access your quote.',
    ], 201);
}

/**
 * GET /quotes/{token}
 *
 * Retrieve a quote by its access token. Returns the full quote with items.
 */
function handle_get_quote(string $token): void
{
    $db    = get_db();
    $quote = get_quote_by_token($db, $token);
    $response = build_quote_response($db, $quote);
    json_response($response);
}

/**
 * PUT /quotes/{token}
 *
 * Update a draft quote's fields and/or replace all items.
 */
function handle_update_quote(string $token): void
{
    $data = get_json_body();
    $ip   = get_client_ip();
    $db   = get_db();

    $quote = update_quote($db, $token, $data, $ip);
    $response = build_quote_response($db, $quote);
    json_response($response);
}

/**
 * POST /quotes/{token}/items
 *
 * Add a single item to a draft quote. HTTP 201 on success.
 */
function handle_add_item(string $token): void
{
    $data = get_json_body();
    $ip   = get_client_ip();
    $db   = get_db();

    // Validate required item fields
    $errors = validate_required($data, ['category', 'product_code', 'product_name', 'unit_price']);
    if (!empty($errors)) {
        error_response('Validation error', 422, $errors);
    }

    $quote = add_item($db, $token, $data, $ip);
    $response = build_quote_response($db, $quote);
    json_response($response, 201);
}

/**
 * DELETE /quotes/{token}/items/{item_id}
 *
 * Remove an item from a draft quote.
 */
function handle_remove_item(string $token, string $item_id): void
{
    $ip = get_client_ip();
    $db = get_db();

    $quote = remove_item($db, $token, $item_id, $ip);
    $response = build_quote_response($db, $quote);
    json_response($response);
}

/**
 * POST /quotes/{token}/submit
 *
 * Submit a draft quote with contact information. Sends an email notification
 * to the admin (best-effort -- email failure does not fail the submission).
 */
function handle_submit_quote(string $token): void
{
    $data = get_json_body();
    $ip   = get_client_ip();
    $db   = get_db();

    // Validate required submission fields
    $errors = validate_required($data, ['company_name', 'contact_name', 'contact_email']);
    if (!empty($errors)) {
        error_response('Validation error', 422, $errors);
    }

    if (!validate_email($data['contact_email'])) {
        error_response('Invalid email address', 422, ["Field 'contact_email' is not a valid email."]);
    }

    // Submit the quote (updates DB)
    $quote = submit_quote($db, $token, $data, $ip);

    // Send email notification (best-effort, do not fail the request)
    try {
        $items_raw = fetch_items_for_quote($db, $quote['id']);
        $items_data = array_map(function ($item) {
            return [
                'service_name'      => $item['product_name'],
                'billing_frequency' => $item['billing_frequency'],
                'unit_price'        => $item['unit_price'],
                'quantity'          => (int)$item['quantity'],
            ];
        }, $items_raw);

        $html = build_quote_notification_html(
            $data['company_name'],
            $data['contact_name'],
            $data['contact_email'],
            $data['contact_phone'] ?? null,
            number_format((float)$quote['monthly_total'], 2, '.', ''),
            number_format((float)$quote['setup_total'], 2, '.', ''),
            $items_data,
            $data['notes'] ?? null
        );

        $subject = "New Quote Submission: {$data['company_name']} - \$" .
                   number_format((float)$quote['monthly_total'], 2, '.', '') . "/mo";

        $sent = send_email(ADMIN_NOTIFICATION_EMAIL, $subject, $html);

        // Update notification record with result
        $notif_status = $sent ? 'sent' : 'failed';
        $notif_error  = $sent ? null : 'Graph API send failed';
        update_notification_status($db, $quote['id'], $notif_status, $notif_error);

    } catch (\Throwable $e) {
        app_log('ERROR', '[ERROR] Failed to send quote notification email: ' . $e->getMessage());
        // Do not fail the submission
    }

    // Return the full quote response
    $response = build_quote_response($db, $quote);
    json_response($response);
}
