<?php
/**
 * Propagarea metadatelor „ale produsului fizic" între conturi, după EAN.
 *
 * Același produs (același EAN) poate exista sub mai multe conturi eMAG. Câmpurile
 * de mai jos descriu PRODUSUL, nu oferta/contul, deci ar trebui să fie identice:
 *   - cod_oblio       (Cod Oblio)
 *   - units_per_box   (Nr. buc / cutie)
 *   - phone bundle    (model principal phone_series_id + serii compatibile + custom_name)
 *   - volumetrie      (length_mm, width_mm, height_mm, weight_g)
 *   - notes           (Notițe)
 *
 * Câmpurile „ale ofertei/contului" NU se ating: emag_id, pnk, emag_part_number,
 * sale_price/current_sale_price, status, product_name.
 *
 * Politică (aleasă de utilizator): „doar completează golurile".
 *   - se copiază o valoare DOAR în câmpurile goale ale celorlalte conturi;
 *   - nu se suprascrie niciodată o valoare existentă;
 *   - dacă două conturi au valori DIFERITE ne-goale → CONFLICT: se raportează,
 *     nu se aplică nimic pe acel câmp (decizie manuală).
 */

require_once __DIR__ . '/db.php';

/** Un câmp e considerat „gol" dacă e NULL sau string vid. */
function _ca_empty($v): bool
{
    return $v === null || $v === '';
}

/**
 * Construiește planul de propagare: grupuri EAN (prezente la ≥2 conturi),
 * cu completările propuse (fills) și conflictele detectate.
 *
 * @return array{groups: array, stats: array{eans:int, fills:int, conflicts:int}}
 */
function cross_account_build_plan(): array
{
    // Toți membrii produselor al căror EAN apare la ≥2 conturi distincte.
    $rows = db_select(
        "SELECT p.id, p.emag_account_id, a.account_name, p.product_name, p.ean,
                p.cod_oblio, p.units_per_box, p.notes,
                p.phone_series_id, p.custom_name,
                p.length_mm, p.width_mm, p.height_mm, p.weight_g,
                ps.name AS series_name, pm.name AS model_name, pb.name AS brand_name
         FROM products p
         JOIN (
             SELECT ean FROM products
             WHERE ean IS NOT NULL AND TRIM(ean) != '' AND emag_account_id IS NOT NULL
             GROUP BY ean
             HAVING COUNT(DISTINCT emag_account_id) >= 2
         ) dup ON dup.ean = p.ean
         LEFT JOIN emag_accounts a ON a.id = p.emag_account_id
         LEFT JOIN phone_series ps ON ps.id = p.phone_series_id
         LEFT JOIN phone_models pm ON pm.id = ps.model_id
         LEFT JOIN phone_brands pb ON pb.id = pm.brand_id
         WHERE p.emag_account_id IS NOT NULL
         ORDER BY p.ean, a.account_name COLLATE NOCASE"
    );

    // Grupare pe EAN, păstrând ordinea.
    $groups = [];
    foreach ($rows as $r) {
        $groups[$r['ean']][] = $r;
    }

    $out = ['groups' => [], 'stats' => ['eans' => 0, 'fills' => 0, 'conflicts' => 0]];

    foreach ($groups as $ean => $members) {
        $fills = [];
        $conflicts = [];

        // ---- Câmpuri scalare (text/int) ----
        $scalars = [
            'cod_oblio'     => 'Cod Oblio',
            'units_per_box' => 'Nr. buc / cutie',
            'notes'         => 'Notițe',
        ];
        foreach ($scalars as $field => $label) {
            $distinct = [];
            $donorVal = null;
            foreach ($members as $m) {
                if (!_ca_empty($m[$field])) {
                    $distinct[(string)$m[$field]] = true;
                    $donorVal = $m[$field];
                }
            }
            if (count($distinct) === 0) continue;
            if (count($distinct) > 1) {
                $conflicts[] = ['field' => $label, 'values' => array_keys($distinct)];
                continue;
            }
            foreach ($members as $m) {
                if (_ca_empty($m[$field])) {
                    $fills[] = [
                        'product_id'   => (int)$m['id'],
                        'account_name' => $m['account_name'],
                        'field'        => $field,
                        'label'        => $label,
                        'to_value'     => (string)$donorVal,
                    ];
                }
            }
        }

        // ---- Bundle telefon (identitate = phone_series_id) ----
        $phoneIds = [];
        $phoneDonor = null;
        foreach ($members as $m) {
            if (!_ca_empty($m['phone_series_id'])) {
                $phoneIds[(int)$m['phone_series_id']] = true;
                if ($phoneDonor === null) $phoneDonor = $m;
            }
        }
        if (count($phoneIds) > 1) {
            $labels = [];
            foreach ($members as $m) {
                if (!_ca_empty($m['phone_series_id'])) {
                    $labels[] = trim(($m['model_name'] ?? '') . ' ' . ($m['series_name'] ?? ''));
                }
            }
            $conflicts[] = ['field' => 'Compatibilitate telefon', 'values' => array_values(array_unique($labels))];
        } elseif (count($phoneIds) === 1 && $phoneDonor) {
            $donorLabel = trim(($phoneDonor['brand_name'] ?? '') . ' ' . ($phoneDonor['model_name'] ?? '') . ' ' . ($phoneDonor['series_name'] ?? ''));
            foreach ($members as $m) {
                if (_ca_empty($m['phone_series_id'])) {
                    $fills[] = [
                        'product_id'   => (int)$m['id'],
                        'account_name' => $m['account_name'],
                        'field'        => 'phone',
                        'label'        => 'Compatibilitate telefon',
                        'to_value'     => $donorLabel ?: ('serie #' . (int)$phoneDonor['phone_series_id']),
                        'meta'         => [
                            'phone_series_id' => (int)$phoneDonor['phone_series_id'],
                            'custom_name'     => $phoneDonor['custom_name'],
                            'donor_id'        => (int)$phoneDonor['id'],
                        ],
                    ];
                }
            }
        }

        // ---- Bundle volumetrie (identitate = tuplu l×w×h/greutate) ----
        $volComplete = fn($m) => !_ca_empty($m['length_mm']) && !_ca_empty($m['width_mm'])
            && !_ca_empty($m['height_mm']) && !_ca_empty($m['weight_g']);
        $volTuples = [];
        $volDonor = null;
        foreach ($members as $m) {
            if ($volComplete($m)) {
                $key = round((float)$m['length_mm'], 2) . 'x' . round((float)$m['width_mm'], 2)
                     . 'x' . round((float)$m['height_mm'], 2) . '/' . round((float)$m['weight_g'], 2);
                $volTuples[$key] = true;
                if ($volDonor === null) $volDonor = $m;
            }
        }
        if (count($volTuples) > 1) {
            $conflicts[] = ['field' => 'Volumetrie', 'values' => array_keys($volTuples)];
        } elseif (count($volTuples) === 1 && $volDonor) {
            foreach ($members as $m) {
                $allEmpty = _ca_empty($m['length_mm']) && _ca_empty($m['width_mm'])
                    && _ca_empty($m['height_mm']) && _ca_empty($m['weight_g']);
                if ($allEmpty) {
                    $fills[] = [
                        'product_id'   => (int)$m['id'],
                        'account_name' => $m['account_name'],
                        'field'        => 'volumetrie',
                        'label'        => 'Volumetrie',
                        'to_value'     => round((float)$volDonor['length_mm'], 2) . '×' . round((float)$volDonor['width_mm'], 2)
                                        . '×' . round((float)$volDonor['height_mm'], 2) . ' mm, ' . round((float)$volDonor['weight_g'], 2) . ' g',
                        'meta'         => [
                            'length_mm' => (float)$volDonor['length_mm'],
                            'width_mm'  => (float)$volDonor['width_mm'],
                            'height_mm' => (float)$volDonor['height_mm'],
                            'weight_g'  => (float)$volDonor['weight_g'],
                        ],
                    ];
                }
            }
        }

        if (empty($fills) && empty($conflicts)) continue; // nimic de raportat pentru acest EAN

        $out['groups'][] = [
            'ean'       => $ean,
            'members'   => array_map(fn($m) => [
                'id'            => (int)$m['id'],
                'account_name'  => $m['account_name'],
                'product_name'  => $m['product_name'],
                'cod_oblio'     => $m['cod_oblio'],
                'units_per_box' => $m['units_per_box'],
                'phone_label'   => trim(($m['brand_name'] ?? '') . ' ' . ($m['model_name'] ?? '') . ' ' . ($m['series_name'] ?? '')) ?: null,
                'vol_complete'  => $volComplete($m) ? 1 : 0,
                'notes'         => $m['notes'],
            ], $members),
            'fills'     => $fills,
            'conflicts' => $conflicts,
        ];
        $out['stats']['eans']++;
        $out['stats']['fills']     += count($fills);
        $out['stats']['conflicts'] += count($conflicts);
    }

    return $out;
}

/**
 * Aplică planul (doar completări, nu suprascrie). Opțional, restrâns la un EAN.
 * Recalculează planul pe server (nu se bazează pe input din client) și execută
 * într-o tranzacție. Fiecare UPDATE re-verifică defensiv golul în WHERE (idempotent).
 *
 * @return array{fields:int, products:int}
 */
function cross_account_apply(?string $ean = null): array
{
    $plan = cross_account_build_plan();
    $fieldsApplied = 0;
    $productsTouched = [];

    $pdo = db();
    $pdo->beginTransaction();
    try {
        foreach ($plan['groups'] as $g) {
            if ($ean !== null && $g['ean'] !== $ean) continue;

            foreach ($g['fills'] as $f) {
                $pid = (int)$f['product_id'];
                switch ($f['field']) {
                    case 'cod_oblio':
                        db_exec("UPDATE products SET cod_oblio = ? WHERE id = ? AND (cod_oblio IS NULL OR cod_oblio = '')",
                            [$f['to_value'], $pid]);
                        break;
                    case 'units_per_box':
                        db_exec("UPDATE products SET units_per_box = ? WHERE id = ? AND units_per_box IS NULL",
                            [(int)$f['to_value'], $pid]);
                        break;
                    case 'notes':
                        db_exec("UPDATE products SET notes = ? WHERE id = ? AND (notes IS NULL OR notes = '')",
                            [$f['to_value'], $pid]);
                        break;
                    case 'phone':
                        $m = $f['meta'];
                        db_exec("UPDATE products SET phone_series_id = ? WHERE id = ? AND phone_series_id IS NULL",
                            [$m['phone_series_id'], $pid]);
                        if (!_ca_empty($m['custom_name'])) {
                            db_exec("UPDATE products SET custom_name = ? WHERE id = ? AND (custom_name IS NULL OR custom_name = '')",
                                [$m['custom_name'], $pid]);
                        }
                        // Copiază seriile compatibile (alt) de la donor, fără duplicate.
                        db_exec(
                            "INSERT OR IGNORE INTO product_phone_series_alt (product_id, phone_series_id)
                             SELECT ?, phone_series_id FROM product_phone_series_alt WHERE product_id = ?",
                            [$pid, (int)$m['donor_id']]
                        );
                        break;
                    case 'volumetrie':
                        $m = $f['meta'];
                        db_exec(
                            "UPDATE products SET length_mm = ?, width_mm = ?, height_mm = ?, weight_g = ?
                             WHERE id = ? AND length_mm IS NULL AND width_mm IS NULL AND height_mm IS NULL AND weight_g IS NULL",
                            [$m['length_mm'], $m['width_mm'], $m['height_mm'], $m['weight_g'], $pid]
                        );
                        break;
                }
                $fieldsApplied++;
                $productsTouched[$pid] = true;
            }
        }
        $pdo->commit();
    } catch (Throwable $e) {
        $pdo->rollBack();
        throw $e;
    }

    return ['fields' => $fieldsApplied, 'products' => count($productsTouched)];
}
