<?php
/**
 * Comparație produse între conturile eMAG.
 *
 * Același produs fizic ar trebui să aibă aceleași date de catalog pe toate
 * conturile: nume, EAN, PNK (part_number_key) și cod produs (emag_part_number).
 *
 * Potrivirea produselor între conturi se face „elastic": două produse sunt
 * considerate ACELAȘI produs dacă împart fie EAN-ul, fie PNK-ul (union-find).
 * Astfel prindem și cazurile în care EAN-ul e identic dar PNK-ul diferă (sau
 * invers) — exact diferențele pe care vrem să le evidențiem.
 *
 * Nu se scrie nimic în DB — pagina e strict read-only (diagnostic).
 */

require_once __DIR__ . '/db.php';

/** Normalizează o valoare de câmp: trim; '' și null → null. */
function _cmp_norm($v): ?string
{
    if ($v === null) return null;
    $v = trim((string)$v);
    return $v === '' ? null : $v;
}

/**
 * Construiește planul de comparație între conturile active.
 *
 * @return array{
 *   accounts: array<int, array{id:int, account_name:string, is_fbe:int}>,
 *   groups: array,
 *   stats: array{total:int, ok:int, diff:int, missing:int}
 * }
 */
function compare_build_plan(): array
{
    $accounts = db_select(
        "SELECT id, account_name, is_fbe FROM emag_accounts
         WHERE is_active = 1
         ORDER BY is_fbe ASC, account_name COLLATE NOCASE ASC"
    );
    $out = ['accounts' => $accounts, 'groups' => [], 'stats' => ['total' => 0, 'ok' => 0, 'diff' => 0, 'missing' => 0]];

    $accIds = array_map(fn($a) => (int)$a['id'], $accounts);
    if (count($accIds) === 0) return $out;

    $ph = implode(',', array_fill(0, count($accIds), '?'));
    $products = db_select(
        "SELECT id, emag_account_id, ean, pnk, product_name, emag_part_number,
                emag_offer_status, current_stock
         FROM products
         WHERE emag_account_id IN ($ph)",
        $accIds
    );

    // ---- Union-find pe chei EAN / PNK ----
    $parent = [];
    $find = function (string $x) use (&$parent): string {
        while ($parent[$x] !== $x) {
            $parent[$x] = $parent[$parent[$x]]; // path halving
            $x = $parent[$x];
        }
        return $x;
    };
    $union = function (string $a, string $b) use (&$parent, $find): void {
        $ra = $find($a); $rb = $find($b);
        if ($ra !== $rb) $parent[$ra] = $rb;
    };

    // Normalizează produsele și înregistrează cheile.
    foreach ($products as &$p) {
        $p['ean']              = _cmp_norm($p['ean']);
        $p['pnk']              = _cmp_norm($p['pnk']);
        $p['product_name']     = _cmp_norm($p['product_name']);
        $p['emag_part_number'] = _cmp_norm($p['emag_part_number']);

        $keys = [];
        if ($p['ean'] !== null) $keys[] = 'e:' . $p['ean'];
        if ($p['pnk'] !== null) $keys[] = 'p:' . $p['pnk'];
        if (!$keys) $keys[] = 'id:' . $p['id'];

        foreach ($keys as $k) {
            if (!isset($parent[$k])) $parent[$k] = $k;
        }
        for ($i = 1, $n = count($keys); $i < $n; $i++) {
            $union($keys[0], $keys[$i]);
        }
        $p['_primary_key'] = $keys[0];
    }
    unset($p);

    // ---- Grupare pe componentă conectată ----
    $groups = [];
    foreach ($products as $p) {
        $root = $find($p['_primary_key']);
        $groups[$root][] = $p;
    }

    $accById = [];
    foreach ($accounts as $a) $accById[(int)$a['id']] = $a;

    $fields = [
        'product_name'     => 'Nume',
        'ean'              => 'EAN',
        'pnk'              => 'PNK',
        'emag_part_number' => 'Cod produs',
    ];

    $result = [];
    foreach ($groups as $members) {
        // Membrii per cont (păstrăm toți; de regulă unul per cont).
        $byAccount = [];
        foreach ($members as $m) {
            $byAccount[(int)$m['emag_account_id']][] = $m;
        }

        // Diferențe per câmp: colectăm valorile distincte non-nule din toți membrii.
        $fieldDiffs = [];
        $anyDiff = false;
        foreach ($fields as $fkey => $flabel) {
            $distinct = [];
            foreach ($members as $m) {
                if ($m[$fkey] !== null) $distinct[$m[$fkey]] = true;
            }
            $isDiff = count($distinct) > 1;
            $fieldDiffs[$fkey] = $isDiff;
            if ($isDiff) $anyDiff = true;
        }

        $presentAccounts = count($byAccount);
        $isMissing = $presentAccounts < count($accIds);

        // Etichetă reprezentativă pentru grup (primul EAN, altfel primul PNK).
        $label = null; $labelKind = null;
        foreach ($members as $m) {
            if ($m['ean'] !== null) { $label = $m['ean']; $labelKind = 'EAN'; break; }
        }
        if ($label === null) {
            foreach ($members as $m) {
                if ($m['pnk'] !== null) { $label = $m['pnk']; $labelKind = 'PNK'; break; }
            }
        }

        // Nume reprezentativ pentru sortare / afișare titlu.
        $repName = null;
        foreach ($members as $m) {
            if ($m['product_name'] !== null) { $repName = $m['product_name']; break; }
        }

        if ($isMissing)      { $status = 'missing'; }
        elseif ($anyDiff)    { $status = 'diff'; }
        else                 { $status = 'ok'; }

        $result[] = [
            'label'      => $label,
            'label_kind' => $labelKind,
            'rep_name'   => $repName,
            'status'     => $status,
            'field_diffs'=> $fieldDiffs,
            'by_account' => $byAccount,
            'present'    => $presentAccounts,
        ];

        $out['stats']['total']++;
        if ($status === 'ok')      $out['stats']['ok']++;
        if ($status === 'diff')    $out['stats']['diff']++;
        if ($status === 'missing') $out['stats']['missing']++;
    }

    // Sortare: întâi problemele (missing, diff), apoi ok; în cadrul fiecăruia după nume.
    $rank = ['diff' => 0, 'missing' => 1, 'ok' => 2];
    usort($result, function ($a, $b) use ($rank) {
        $ra = $rank[$a['status']]; $rb = $rank[$b['status']];
        if ($ra !== $rb) return $ra <=> $rb;
        return strcasecmp((string)$a['rep_name'], (string)$b['rep_name']);
    });

    $out['groups'] = $result;
    $out['fields'] = $fields;
    return $out;
}
