<?php
declare(strict_types=1);
if (isset($_GET['debug'])) {
  ini_set('display_errors', '1');
  error_reporting(E_ALL);
}
ob_start();
require_once __DIR__ . '/_inc/boot.php';
require_once __DIR__ . '/_inc/db.php';

$pdo = db();
auth_require_any_permission(['use_crons', 'manage_settings']);

function pp_import_key(string $value): string {
  $value = strtolower(trim($value));
  if (function_exists('iconv')) {
    $converted = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
    if (is_string($converted) && $converted !== '') $value = strtolower($converted);
  }
  return preg_replace('/[^a-z0-9]/', '', $value) ?: $value;
}

function pp_import_cells(string $line): array {
  $tabs = substr_count($line, "\t");
  $semis = substr_count($line, ';');
  $commas = substr_count($line, ',');
  $delimiter = "\t";
  if ($semis >= $tabs && $semis >= $commas) $delimiter = ';';
  if ($commas > $tabs && $commas > $semis) $delimiter = ',';
  return str_getcsv($line, $delimiter);
}

function pp_import_id(string $value): string {
  $value = trim($value, " \t\n\r\0\x0B\"'");
  if (preg_match('/^PP[-_\s]*(.+)$/i', $value, $m)) $value = trim((string)$m[1]);
  $value = preg_replace('/[^A-Za-z0-9_-]/', '', $value) ?: '';
  if ($value === '' || !preg_match('/\d/', $value)) return '';
  return (strlen($value) >= 3 && strlen($value) <= 64) ? $value : '';
}

function pp_import_parse(string $raw, int $max): array {
  $raw = str_replace(["\r\n", "\r"], "\n", $raw);
  $lines = [];
  foreach (explode("\n", $raw) as $line) {
    $line = trim((string)$line);
    if ($line !== '') $lines[] = $line;
  }

  $idHeaders = ['id' => true, 'shipmentid' => true, 'shipment' => true, 'shipmentnumber' => true, 'brojposiljke' => true];
  $knownHeaders = ['trackingawb' => true, 'courier' => true, 'channel' => true, 'itemcount' => true, 'company' => true, 'shipmenttype' => true, 'status' => true, 'ordernumber' => true, 'receiver' => true, 'receiverphone' => true, 'receiveremail' => true, 'city' => true, 'zip' => true, 'country' => true, 'codamount' => true, 'iscod' => true, 'creationdate' => true];
  $headerLine = null;
  $idCol = null;
  $keys = [];
  $scanLimit = min(8, count($lines));
  for ($i = 0; $i < $scanLimit; $i++) {
    $cells = pp_import_cells($lines[$i]);
    $rowKeys = [];
    $knownCount = 0;
    foreach ($cells as $idx => $cell) {
      $key = pp_import_key((string)$cell);
      $rowKeys[$idx] = $key;
      if (isset($knownHeaders[$key])) $knownCount++;
    }
    foreach ($rowKeys as $idx => $key) {
      if (isset($idHeaders[$key]) && ($key !== 'id' || $knownCount >= 3)) {
        $headerLine = $i;
        $idCol = $idx;
        $keys = $rowKeys;
        break 2;
      }
    }
  }

  $rows = [];
  $seen = [];
  $push = static function(string $candidate, array $csv) use (&$rows, &$seen, $max): void {
    if (count($rows) >= $max) return;
    $id = pp_import_id($candidate);
    if ($id === '' || isset($seen[$id])) return;
    $seen[$id] = true;
    $rows[] = [
      'shipment_id' => $id,
      'country' => strtoupper(trim((string)($csv['country'] ?? ''))),
      'csv' => $csv,
    ];
  };

  if ($headerLine !== null && $idCol !== null) {
    for ($i = $headerLine + 1; $i < count($lines); $i++) {
      $cells = pp_import_cells($lines[$i]);
      if (!array_key_exists($idCol, $cells)) continue;
      $csv = [];
      foreach ($keys as $idx => $key) {
        if ($key === '' || !array_key_exists($idx, $cells)) continue;
        $csv[$key] = trim((string)$cells[$idx]);
      }
      $push((string)$cells[$idCol], $csv);
    }
    return $rows;
  }

  foreach ($lines as $line) {
    if (preg_match('/^\d{3,20}$/', $line)) {
      $push($line, []);
      continue;
    }
    if (preg_match_all('/\bPP[-_\s]*(\d{3,20})\b/i', $line, $m)) {
      foreach ($m[1] as $candidate) $push((string)$candidate, []);
    }
  }
  return $rows;
}

function pp_import_get(array $csv, array $keys, string $default = ''): string {
  foreach ($keys as $key) {
    $norm = pp_import_key($key);
    if (!array_key_exists($norm, $csv)) continue;
    $value = trim((string)$csv[$norm]);
    if ($value !== '') return $value;
  }
  return $default;
}

function pp_import_country(PDO $pdo, string $country, string $fallback): string {
  $country = strtoupper(trim($country !== '' ? $country : $fallback));
  if ($country === '') return 'PICKPACK';
  $aliases = [
    'HR' => ['CROATIA', 'CROACIA', 'HRVATSKA'],
    'CRO' => ['CROATIA'],
    'CROACIA' => ['CROATIA'],
    'SI' => ['SLOVENIA', 'SLOVENIJA'],
    'SLO' => ['SLOVENIA'],
    'CZ' => ['CZ', 'CZECHIA', 'CZECH', 'CZECH REPUBLIC', 'CZECH_REPUBLIC'],
    'PT' => ['PORTUGAL'],
    'AT' => ['AUSTRIA'],
    'FR' => ['FRANCE'],
  ];
  $candidates = [$country];
  if (isset($aliases[$country])) {
    foreach ($aliases[$country] as $alias) $candidates[] = $alias;
  }
  foreach (array_values(array_unique($candidates)) as $candidate) {
    $resolved = resolve_country_code($pdo, $candidate);
    if ($resolved) return $resolved;
    try {
      $st = $pdo->prepare("SELECT code FROM countries WHERE UPPER(code)=? OR UPPER(api_value)=? LIMIT 1");
      $st->execute([$candidate, $candidate]);
      $code = $st->fetchColumn();
      if ($code) return (string)$code;
    } catch (Throwable $e) {
      // Keep fallback candidate below.
    }
  }
  return $candidates[0];
}

function pp_import_status(string $raw): string {
  $s = strtolower(trim($raw));
  if (function_exists('iconv')) {
    $converted = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
    if (is_string($converted) && $converted !== '') $s = strtolower($converted);
  }
  if ($s === '') return 'created';
  if (strpos($s, 'dostavljeno') !== false || strpos($s, 'delivered') !== false || strpos($s, 'isporuceno') !== false) return 'delivered';
  if (strpos($s, 'dostava u tijeku') !== false || strpos($s, 'dostava u toku') !== false || strpos($s, 'in delivery') !== false) return 'in_delivery';
  if (strpos($s, 'posiljka unesena') !== false || strpos($s, 'shipment entered') !== false) return 'processing';
  if (strpos($s, 'adresnica kreirana') !== false || strpos($s, 'label created') !== false) return 'confirmed';
  return normalize_status($raw);
}

function pp_import_dt(string $raw): ?string {
  $raw = trim($raw);
  if ($raw === '') return null;
  foreach (['Y-m-d H:i:s', 'd-m-Y H:i:s', 'd.m.Y H:i:s'] as $fmt) {
    $dt = DateTimeImmutable::createFromFormat($fmt, $raw);
    if ($dt instanceof DateTimeImmutable) return $dt->format('Y-m-d H:i:s');
  }
  $ts = strtotime($raw);
  return $ts === false ? null : date('Y-m-d H:i:s', $ts);
}

function pp_import_decimal(string $raw): ?float {
  $raw = trim($raw);
  if ($raw === '') return null;
  $raw = str_replace(['.', ','], ['', '.'], $raw);
  return is_numeric($raw) ? (float)$raw : null;
}

function pp_import_seed(PDO $pdo, array $row, string $fallbackCountry): array {
  $shipmentId = pp_import_id((string)($row['shipment_id'] ?? ''));
  if ($shipmentId === '') throw new RuntimeException('Invalid shipmentID.');
  $csv = (!empty($row['csv']) && is_array($row['csv'])) ? $row['csv'] : [];
  $country = pp_import_country($pdo, pp_import_get($csv, ['country'], (string)($row['country'] ?? '')), $fallbackCountry);
  $lead = 'PP-' . $shipmentId;
  $now = now_dt();
  $statusRaw = pp_import_get($csv, ['status'], 'Imported from Pick&Pack CSV');
  $status = pp_import_status($statusRaw);
  $created = pp_import_dt(pp_import_get($csv, ['creation date', 'creationdate', 'created at'])) ?? $now;
  $tracking = pp_import_get($csv, ['tracking awb', 'trackingawb', 'awb']);
  $courier = pp_import_get($csv, ['courier', 'carrier']);
  $receiver = pp_import_get($csv, ['receiver']);
  $phone = pp_import_get($csv, ['receiver phone', 'receiverphone', 'phone']);
  $email = pp_import_get($csv, ['receiver email', 'receiveremail', 'email']);
  $city = pp_import_get($csv, ['city']);
  $zip = pp_import_get($csv, ['zip', 'zipcode']);
  $qtyRaw = pp_import_get($csv, ['item count', 'itemcount', 'qty', 'quantity']);
  $qty = is_numeric(str_replace(',', '.', $qtyRaw)) ? max(0, (int)round((float)str_replace(',', '.', $qtyRaw))) : 0;
  $total = pp_import_decimal(pp_import_get($csv, ['cod amount', 'codamount']));
  $payment = ($total !== null && $total > 0) ? 'COD' : 'PREPAID';
  $itemsJson = $qty > 0 ? json_encode([['sku' => '', 'name' => 'Pick&Pack CSV item count', 'quantity' => $qty]], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null;
  $detailsJson = json_encode(['provider' => 'PICKPACK', 'source' => 'pickpack_csv', 'shipment_id' => $shipmentId, 'csv' => $csv], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

  $st = $pdo->prepare("INSERT INTO leads(
      lead_number,country,customer_name,email,phone,total,payment_type,zipcode,city,
      created_at_remote,current_status,current_status_at,final_status,tracking_number,courier_code,
      shipping_company,order_id_remote,qty_cards,items_json,details_json,last_sync_job,last_sync_at,created_at,updated_at
    ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
    ON DUPLICATE KEY UPDATE
      country=VALUES(country), customer_name=COALESCE(NULLIF(VALUES(customer_name),''), customer_name),
      email=COALESCE(NULLIF(VALUES(email),''), email), phone=COALESCE(NULLIF(VALUES(phone),''), phone),
      total=COALESCE(VALUES(total), total), payment_type=COALESCE(NULLIF(VALUES(payment_type),''), payment_type),
      zipcode=COALESCE(NULLIF(VALUES(zipcode),''), zipcode), city=COALESCE(NULLIF(VALUES(city),''), city),
      current_status=VALUES(current_status), current_status_at=VALUES(current_status_at), final_status=VALUES(final_status),
      tracking_number=COALESCE(NULLIF(VALUES(tracking_number),''), tracking_number),
      courier_code=COALESCE(NULLIF(VALUES(courier_code),''), courier_code),
      shipping_company=COALESCE(NULLIF(VALUES(shipping_company),''), shipping_company),
      order_id_remote=VALUES(order_id_remote), qty_cards=COALESCE(VALUES(qty_cards), qty_cards),
      items_json=COALESCE(VALUES(items_json), items_json), details_json=COALESCE(VALUES(details_json), details_json),
      last_sync_job=VALUES(last_sync_job), last_sync_at=VALUES(last_sync_at), updated_at=VALUES(updated_at)");
  $st->execute([$lead, $country, $receiver, $email, $phone, $total, $payment, $zip, $city, $created, $status, $created, is_final_status($status) ? 1 : 0, $tracking ?: null, $courier ?: null, $courier ?: null, $shipmentId, $qty ?: null, $itemsJson, $detailsJson, 'pickpack_csv_import', $now, $now, $now]);

  try {
    $pdo->prepare("INSERT IGNORE INTO lead_history(lead_number,status_raw,status_norm,status_at,note,created_at) VALUES(?,?,?,?,?,?)")
      ->execute([$lead, $statusRaw, $status, $created, 'Pick&Pack CSV import', $now]);
  } catch (Throwable $e) {
    // History insert must not break import.
  }

  return ['ok' => true, 'shipment_id' => $shipmentId, 'lead_number' => $lead, 'country' => $country, 'tracking_number' => $tracking, 'courier_code' => $courier, 'history_rows' => 1, 'products' => $qty > 0 ? 1 : 0, 'qty_cards' => $qty];
}

$title = 'Pick&Pack import';
$active = 'crons';

$pickpackCountries = [];
try {
  $pickpackCountries = $pdo->query("SELECT code,name FROM countries WHERE COALESCE(fulfillment_provider,'EFC')='PICKPACK' ORDER BY name")->fetchAll();
} catch (Throwable $e) {
  try {
    $pickpackCountries = $pdo->query("SELECT code,name FROM countries ORDER BY name")->fetchAll();
  } catch (Throwable $e2) {
    $pickpackCountries = [];
  }
}
$fallbackCountry = strtoupper(trim((string)($_POST['fallback_country'] ?? ($pickpackCountries[0]['code'] ?? ''))));
$limit = isset($_POST['limit']) ? max(1, min(200, (int)$_POST['limit'])) : 50;
$fetchLive = (string)($_POST['fetch_live'] ?? '') === '1';
$raw = (string)($_POST['shipment_ids'] ?? '');
$results = [];
$parsedIds = [];
$parsedRows = [];
$errorMsg = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if (!empty($_FILES['shipment_file']['tmp_name']) && is_uploaded_file((string)$_FILES['shipment_file']['tmp_name'])) {
    $fileText = (string)file_get_contents((string)$_FILES['shipment_file']['tmp_name']);
    $raw .= "\n" . $fileText;
  }

  $parsedRows = pp_import_parse($raw, $limit);
  $parsedIds = [];
  foreach ($parsedRows as $parsedRow) {
    $parsedIds[] = (string)($parsedRow['shipment_id'] ?? '');
  }
  if (!$parsedRows) {
    if ($errorMsg === '') $errorMsg = 'No shipmentID values found. Use one shipmentID per line or Pick&Pack CSV with ID column.';
  } else {
    try {
      $client = null;
      foreach ($parsedRows as $row) {
        $shipmentId = (string)($row['shipment_id'] ?? '');
        $rowCountry = strtoupper(trim((string)($row['country'] ?? '')));
        $rowFallbackCountry = $rowCountry !== '' ? $rowCountry : $fallbackCountry;
        try {
          $hasCsvFields = !empty($row['csv']) && is_array($row['csv']);
          if ($hasCsvFields && !$fetchLive) {
            $results[] = pp_import_seed($pdo, $row, $rowFallbackCountry);
          } else {
            require_once __DIR__ . '/_inc/pickpack_sync.php';
            if (!$client) $client = new PickPackClient();
            $results[] = pickpack_import_shipment($pdo, $client, $shipmentId, $rowFallbackCountry, 'pickpack_import');
          }
        } catch (Throwable $e) {
          $results[] = [
            'ok' => false,
            'shipment_id' => $shipmentId,
            'country' => $rowCountry,
            'error' => $e->getMessage(),
          ];
        }
      }
    } catch (Throwable $e) {
      $errorMsg = $e->getMessage();
    }
  }
}

$okCount = 0;
$failCount = 0;
foreach ($results as $r) {
  if (!empty($r['ok'])) $okCount++;
  else $failCount++;
}

require_once __DIR__ . '/_inc/layout_top.php';
?>

<section class="card wide">
  <div class="card-h">
    <div>
      <div class="card-title">Pick&Pack import shipments</div>
      <div class="muted">Imports Pick&Pack ID values and uses Country per CSV row. CSV import is saved first; cron can refresh live details after.</div>
    </div>
    <a class="btn btn-ghost" href="/crons.php">Back to crons</a>
  </div>

  <div class="bd">
    <?php if($errorMsg !== ''): ?>
      <div class="pill" style="border-color:rgba(239,68,68,.45); margin-bottom:12px"><?= h($errorMsg) ?></div>
    <?php endif; ?>

    <form method="post" enctype="multipart/form-data">
      <div class="grid-2" style="gap:14px">
        <div>
          <div class="muted small" style="margin-bottom:6px">Paste shipmentID list or Pick&Pack CSV</div>
          <textarea class="input" name="shipment_ids" rows="12" style="width:100%; min-width:0; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" placeholder="ID&#9;Tracking AWB&#9;Courier&#9;...&#9;Country&#10;3688754&#9;17502058263623&#9;DPD Hrvatska&#9;...&#9;HR"><?= h($raw) ?></textarea>
        </div>
        <div>
          <div class="panel">
            <div class="panel-h">
              <div class="panel-t">Options</div>
              <div class="muted small">CSV default: 0 API calls</div>
            </div>

            <div class="row" style="align-items:end">
              <div style="min-width:220px">
                <div class="muted small" style="margin-bottom:6px">Fallback country if API data cannot resolve it</div>
                <select class="input" name="fallback_country" style="width:100%">
                  <?php if(empty($pickpackCountries)): ?>
                    <option value="">No Pick&Pack countries configured</option>
                  <?php else: ?>
                    <?php foreach($pickpackCountries as $c): ?>
                      <option value="<?= h($c['code']) ?>" <?= $fallbackCountry===$c['code']?'selected':'' ?>><?= h($c['name']) ?> (<?= h($c['code']) ?>)</option>
                    <?php endforeach; ?>
                  <?php endif; ?>
                </select>
              </div>
              <div style="min-width:120px">
                <div class="muted small" style="margin-bottom:6px">Max import</div>
                <input class="input" type="number" name="limit" min="1" max="200" value="<?= (int)$limit ?>" style="width:120px; min-width:0">
              </div>
            </div>

            <div class="sep"></div>

            <div class="muted small" style="margin-bottom:6px">CSV/TXT file (optional)</div>
            <input class="input" type="file" name="shipment_file" accept=".csv,.txt,text/csv,text/plain" style="width:100%; min-width:0">

            <div class="sep"></div>

            <label class="cb" title="Slow: calls Pick&Pack API while importing. Leave off for large CSV files.">
              <input type="checkbox" name="fetch_live" value="1" <?= $fetchLive ? 'checked' : '' ?> />
              <span>Fetch live details now</span>
            </label>

            <div class="sep"></div>
            <button class="btn primary" type="submit">Import from Pick&Pack</button>
          </div>

          <div class="muted" style="margin-top:10px">
            This cannot discover unknown shipments by itself because the documented Pick&Pack API needs a shipmentID.
            In Pick&Pack export, ID is shipmentID; Tracking AWB is courier tracking.
          </div>
        </div>
      </div>
    </form>
  </div>
</section>

<?php if($_SERVER['REQUEST_METHOD'] === 'POST'): ?>
<section class="card wide" style="margin-top:16px">
  <div class="card-h">
    <div class="card-title">Import result</div>
    <div class="muted">Parsed <?= count($parsedIds) ?> IDs · OK <?= (int)$okCount ?> · Failed <?= (int)$failCount ?></div>
  </div>
  <div class="table-wrap">
    <table class="table">
      <thead>
        <tr>
          <th>ShipmentID</th>
          <th>Lead</th>
          <th>Country</th>
          <th>Tracking</th>
          <th>Courier</th>
          <th class="right">History</th>
          <th class="right">Products</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        <?php foreach($results as $r): ?>
          <tr>
            <td class="mono"><?= h($r['shipment_id'] ?? '') ?></td>
            <td>
              <?php if(!empty($r['lead_number'])): ?>
                <a class="lead-link" href="/lead.php?lead=<?= urlencode((string)$r['lead_number']) ?>"><?= h($r['lead_number']) ?></a>
              <?php else: ?>
                <span class="muted">-</span>
              <?php endif; ?>
            </td>
            <td><?= h($r['country'] ?? '') ?></td>
            <td class="mono"><?= h($r['tracking_number'] ?? '') ?></td>
            <td><?= h($r['courier_code'] ?? '') ?></td>
            <td class="right"><?= isset($r['history_rows']) ? (int)$r['history_rows'] : 0 ?></td>
            <td class="right"><?= isset($r['products']) ? (int)$r['products'] : 0 ?></td>
            <td>
              <?php if(!empty($r['ok'])): ?>
                <span class="badge badge-good">OK</span>
              <?php else: ?>
                <span class="badge badge-bad">ERROR</span>
                <div class="muted small"><?= h($r['error'] ?? '') ?></div>
              <?php endif; ?>
            </td>
          </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
  </div>
</section>
<?php endif; ?>

<?php require_once __DIR__ . '/_inc/layout_bottom.php'; ?>
