<?php
/**
 * Door configurations API for storefront.
 *
 * POST   – save new configuration (customerEmail, baseProductId, productTitle?, productImageUrl?, productHandle?, options, notesFromCustomer?, basePrice?, computedPrice?)
 * GET    – ?email=xxx list configs for email; ?id=123&email=xxx get one (email required for ownership)
 * PUT    – update configuration (id, email, options?, basePrice?, computedPrice?, notesFromCustomer?); email must match
 *
 * computed_price is taken from the storefront snapshot (options._applied_unit_price or computedPrice in JSON body),
 * not recalculated server-side, so API add-ons (sidelight/transom, storm glass, seal kit, measurements, etc.) persist.
 */
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: https://shopify.vintagedoors.com');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

require __DIR__ . '/../admin/config.php';

$helpersPath = __DIR__ . '/../admin_config_helpers.php';
if (!is_file($helpersPath)) {
    $helpersPath = __DIR__ . '/../admin/admin_config_helpers.php';
}
if (is_file($helpersPath)) {
    require_once $helpersPath;
}

/**
 * Resolve unit price from storefront save snapshot (never server-side schema recalc).
 */
function configurations_api_resolve_computed_price(array $options, float $basePrice, $payloadComputed = null) {
    if (function_exists('admin_get_applied_unit_price')) {
        $fromPayload = ($payloadComputed !== null && $payloadComputed !== '' && is_numeric($payloadComputed))
            ? (float) $payloadComputed
            : null;
        return admin_get_applied_unit_price($options, $basePrice, $fromPayload);
    }
    if (isset($options['_applied_unit_price']) && $options['_applied_unit_price'] !== '' && is_numeric($options['_applied_unit_price'])) {
        return round((float) $options['_applied_unit_price'], 2);
    }
    if ($payloadComputed !== null && $payloadComputed !== '' && is_numeric($payloadComputed)) {
        return round((float) $payloadComputed, 2);
    }
    return round($basePrice, 2);
}

function configurations_api_folder_name(PDO $pdo, $folderId) {
    $folderId = (int) $folderId;
    if ($folderId <= 0) {
        return null;
    }
    $stmt = $pdo->prepare('SELECT name FROM door_folders WHERE id = ? LIMIT 1');
    $stmt->execute([$folderId]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    return $row ? (string) ($row['name'] ?? '') : null;
}

function configurations_api_resolve_folder_id(PDO $pdo, $email, $data) {
    if (array_key_exists('folder_id', $data) && $data['folder_id'] !== null && $data['folder_id'] !== '') {
        return (int) $data['folder_id'];
    }
    $folderName = trim((string) ($data['folder_name'] ?? ($data['folderName'] ?? '')));
    if ($folderName === '' || $email === '') {
        return null;
    }
    $stmt = $pdo->prepare('SELECT id FROM door_folders WHERE customer_email = ? AND name = ? LIMIT 1');
    $stmt->execute([$email, $folderName]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row) {
        return (int) $row['id'];
    }
    $ins = $pdo->prepare('INSERT INTO door_folders (name, customer_email) VALUES (?, ?)');
    $ins->execute([$folderName, $email]);
    return (int) $pdo->lastInsertId();
}

function configurations_api_merge_options(array $existing, array $incoming) {
    if (function_exists('admin_merge_incoming_configuration_options')) {
        return admin_merge_incoming_configuration_options($existing, $incoming);
    }
    foreach ($incoming as $k => $v) {
        $existing[$k] = $v;
    }
    return $existing;
}

/** Normalize casing from Shopify payload (_casing_selections, summary, line props). */
function configurations_api_finalize_options(array $options) {
    if (function_exists('admin_merge_shopify_casing_into_options')) {
        return admin_merge_shopify_casing_into_options($options);
    }
    return $options;
}

function configurations_api_enrich_post_options(array $options, array $data) {
    if (!empty($data['productTitle'])) {
        $options['_product_title'] = $data['productTitle'];
    }
    if (!empty($data['productImageUrl'])) {
        $options['_product_image_url'] = $data['productImageUrl'];
    }
    if (!empty($data['productHandle'])) {
        $options['_product_handle'] = $data['productHandle'];
    }
    if (!empty($data['variantId'])) {
        $options['_variant_id'] = (string) $data['variantId'];
    }
    if (!empty($data['baseProductId'])) {
        $options['_product_id'] = (string) $data['baseProductId'];
    }
    // Legacy: pricingSchema sent separately; options may already include _pricing_schema from door-conf2.js.
    if (isset($data['pricingSchema']) && is_array($data['pricingSchema']) && empty($options['_pricing_schema'])) {
        $options['_pricing_schema'] = $data['pricingSchema'];
    }
    return $options;
}

$method = $_SERVER['REQUEST_METHOD'];

// ---------- GET: list by email or get one by id+email ----------
if ($method === 'GET') {
    $email = trim($_GET['email'] ?? '');
    $id    = isset($_GET['id']) ? (int) $_GET['id'] : 0;

    if ($email === '') {
        http_response_code(400);
        echo json_encode(['error' => 'email is required']);
        exit;
    }

    if ($id > 0) {
        $stmt = $pdo->prepare('SELECT * FROM door_configurations WHERE id = ? AND customer_email = ?');
        $stmt->execute([$id, $email]);
        $config = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$config) {
            http_response_code(404);
            echo json_encode(['error' => 'Not found or access denied']);
            exit;
        }
        $config['options'] = configurations_api_finalize_options(json_decode($config['options_json'], true) ?: []);
        unset($config['options_json']);
        $config['folder_name'] = configurations_api_folder_name($pdo, $config['folder_id'] ?? 0);
        echo json_encode($config);
        exit;
    }

    $stmt = $pdo->prepare(
        'SELECT c.id, c.customer_email, c.base_product_id, c.options_json, c.status,
                c.base_price, c.computed_price, c.created_at, c.folder_id, f.name AS folder_name
         FROM door_configurations c
         LEFT JOIN door_folders f ON f.id = c.folder_id
         WHERE c.customer_email = ?
         ORDER BY c.created_at DESC'
    );
    $stmt->execute([$email]);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $list = [];
    foreach ($rows as $r) {
        $opts = json_decode($r['options_json'], true) ?: [];
        $list[] = [
            'id'                => (int) $r['id'],
            'customer_email'    => $r['customer_email'],
            'base_product_id'   => $r['base_product_id'],
            'product_title'     => $opts['_product_title'] ?? '',
            'product_image_url' => $opts['_product_image_url'] ?? '',
            'product_handle'    => $opts['_product_handle'] ?? '',
            'product_type'      => $opts['_product_type'] ?? '',
            'status'            => $r['status'],
            'base_price'        => (float) $r['base_price'],
            'computed_price'    => (float) $r['computed_price'],
            'applied_unit_price'=> isset($opts['_applied_unit_price']) ? (float) $opts['_applied_unit_price'] : (float) $r['computed_price'],
            'created_at'        => $r['created_at'],
            'folder_id'         => isset($r['folder_id']) ? (int) $r['folder_id'] : null,
            'folder_name'       => isset($r['folder_name']) && $r['folder_name'] !== '' ? (string) $r['folder_name'] : null,
        ];
    }
    echo json_encode($list);
    exit;
}

// ---------- PUT: update configuration (customer must send email to verify) ----------
if ($method === 'PUT') {
    $raw = file_get_contents('php://input');
    $data = json_decode($raw, true);
    if (!$data || empty($data['email']) || empty($data['id'])) {
        http_response_code(400);
        echo json_encode(['error' => 'id and email are required']);
        exit;
    }

    $id = (int) $data['id'];
    $email = trim((string) $data['email']);

    $stmt = $pdo->prepare('SELECT * FROM door_configurations WHERE id = ? AND customer_email = ?');
    $stmt->execute([$id, $email]);
    $config = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$config) {
        http_response_code(404);
        echo json_encode(['error' => 'Not found or access denied']);
        exit;
    }

    $options = json_decode($config['options_json'], true) ?: [];
    if (isset($data['options']) && is_array($data['options'])) {
        $options = configurations_api_merge_options($options, $data['options']);
    }
    $options = configurations_api_finalize_options($options);

    $basePrice = isset($data['basePrice']) ? (float) $data['basePrice'] : (float) $config['base_price'];
    $notesCustomer = array_key_exists('notesFromCustomer', $data)
        ? $data['notesFromCustomer']
        : ($config['notes_customer'] ?? '');
    $computedPrice = configurations_api_resolve_computed_price(
        $options,
        $basePrice,
        $data['computedPrice'] ?? ($data['appliedUnitPrice'] ?? null)
    );

    $folderId = configurations_api_resolve_folder_id($pdo, $email, $data);
    if ($folderId === null && !empty($config['folder_id'])) {
        $folderId = (int) $config['folder_id'];
    }

    $up = $pdo->prepare(
        'UPDATE door_configurations
         SET options_json = ?, base_price = ?, computed_price = ?, notes_customer = ?, folder_id = ?
         WHERE id = ?'
    );
    $up->execute([
        json_encode($options),
        $basePrice,
        $computedPrice,
        $notesCustomer,
        $folderId ?: null,
        $id,
    ]);

    echo json_encode([
        'id'             => $id,
        'computedPrice'  => $computedPrice,
        'computed_price' => $computedPrice,
        'folder_id'      => $folderId,
    ]);
    exit;
}

// ---------- POST: save new configuration ----------
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (!$data || empty($data['customerEmail'])) {
    http_response_code(400);
    echo json_encode(['error' => 'customerEmail is required']);
    exit;
}

$options = isset($data['options']) && is_array($data['options']) ? $data['options'] : [];
$options = configurations_api_enrich_post_options($options, $data);
$options = configurations_api_finalize_options($options);

$customerEmail = trim((string) $data['customerEmail']);
$baseProductId = $data['baseProductId'] ?? null;
$notesCustomer   = $data['notesFromCustomer'] ?? '';
$basePrice       = isset($data['basePrice']) ? (float) $data['basePrice'] : 0.0;
$computedPrice   = configurations_api_resolve_computed_price(
    $options,
    $basePrice,
    $data['computedPrice'] ?? ($data['appliedUnitPrice'] ?? null)
);

$folderId = configurations_api_resolve_folder_id($pdo, $customerEmail, $data);

$sql = 'INSERT INTO door_configurations
        (customer_email, base_product_id, options_json, notes_customer, status, base_price, computed_price, folder_id)
        VALUES (:email, :product, :options, :notes_customer, :status, :base_price, :computed_price, :folder_id)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
    ':email'          => $customerEmail,
    ':product'        => $baseProductId,
    ':options'        => json_encode($options),
    ':notes_customer' => $notesCustomer,
    ':status'         => 'draft',
    ':base_price'     => $basePrice,
    ':computed_price' => $computedPrice,
    ':folder_id'      => $folderId ?: null,
]);

$id = (int) $pdo->lastInsertId();
echo json_encode([
    'id'             => $id,
    'folder_id'      => $folderId,
    'computedPrice'  => $computedPrice,
    'computed_price' => $computedPrice,
]);
