<?php
/* ============================================================================
   WBMCZ — Admin · Bulk Import (Government Portals & every other category)

   Upload one CSV and create many `seller_services` rows in a single go.

     Step 1  choose the category (+ default sub-category) and pick the file
     Step 2  the file is parsed and every row is shown with a verdict
             (OK / duplicate / error) — nothing is written yet
     Step 3  press Import and only the good rows are inserted

   Imported rows are owned by the admin who uploads them and go live straight
   away (status = 1), because these are the company's own portals.

   `?template=1` downloads a ready-made sample CSV.
   ============================================================================ */

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../db.php';
require_once __DIR__ . '/../includes/functions.php';
require_once __DIR__ . '/../includes/Language.php';
require_once __DIR__ . '/../includes/admin_list.php';
require_once __DIR__ . '/../includes/shares.php';
$WB_IMP_ROOT = dirname(__DIR__);

if (!isLoggedIn() || !isAdmin()) { redirect('login.php'); }
if (!hasPermission('manage_services')) { die("Access Denied: You do not have permission to manage services."); }

/* ---------------------------------------------------------------------------
   COMING FROM A CATEGORY PAGE

   Every category page has a Bulk upload panel that posts straight here, with
   the category already decided. When it does, the category box is shown as a
   fixed label rather than a menu — you cannot start on the Government Portals
   page and land the rows in Shopping — and after the import this screen sends
   you back where you started.

   `back` is reduced to a bare file name, so it can only ever point at another
   page of this admin panel.
   --------------------------------------------------------------------------- */
$IMP_LOCK = !empty($_POST['lock_cat']) || !empty($_GET['lock_cat']);
$IMP_BACK = (string)($_POST['back'] ?? $_GET['back'] ?? '');
$IMP_BACK = preg_match('/^[A-Za-z0-9_\-]+\.php$/', $IMP_BACK) ? $IMP_BACK : '';
$IMP_HIDDEN = ($IMP_LOCK ? '<input type="hidden" name="lock_cat" value="1">' : '')
            . ($IMP_BACK !== '' ? '<input type="hidden" name="back" value="' . htmlspecialchars($IMP_BACK) . '">' : '');

$lang         = new Language($db);
$current_lang = $lang->getCurrentLanguage();
$user_id      = (int)$_SESSION['user_id'];

/* sidebar permission flags */
$can_users        = hasPermission('manage_users');
$can_sellers      = hasPermission('manage_sellers');
$can_staff        = hasPermission('manage_staff_roles');
$can_services     = hasPermission('manage_services');
$can_orders       = hasPermission('manage_orders');
$can_transactions = hasPermission('manage_transactions');
$can_tickets      = hasPermission('manage_tickets');
$can_settings     = hasPermission('manage_settings');

try { shares_ensure_schema($db); } catch (\Throwable $e) {}

/* who is importing */
$me_name = 'this admin';
try {
    $__me = $db->select("SELECT name FROM users WHERE id = ?", [$user_id]);
    if (!empty($__me)) $me_name = (string)$__me[0]['name'];
} catch (\Throwable $e) {}

if (isset($_SESSION['flash_success'])) { $success_msg = $_SESSION['flash_success']; unset($_SESSION['flash_success']); }
if (isset($_SESSION['flash_error']))   { $error_msg   = $_SESSION['flash_error'];   unset($_SESSION['flash_error']); }

/* ---------------------------------------------------------------------------
   The columns a CSV may carry. Key = internal name, value = accepted headers.
   --------------------------------------------------------------------------- */
$IMP_COLS = [
    'title'                    => ['title', 'name', 'portal', 'portal name', 'service', 'service name'],
    'description'              => ['description', 'desc', 'details', 'about'],
    'web_url'                  => ['web_url', 'url', 'website', 'link', 'web link', 'portal url'],
    'app_url'                  => ['app_url', 'app', 'app link', 'play store', 'android'],
    'tutorial_url'             => ['tutorial_url', 'tutorial', 'video', 'youtube', 'help video'],
    'icon_class'               => ['icon_class', 'icon', 'image', 'image_url', 'logo'],
    'color_class'              => ['color_class', 'color', 'colour'],
    'price'                    => ['price', 'mrp', 'rate', 'amount'],
    'discount_price'           => ['discount_price', 'selling price', 'sale price', 'offer price'],
    'sub_category'             => ['sub_category', 'sub category', 'subcategory', 'sub_cat', 'group'],
    'status'                   => ['status', 'active'],
    'seller_share_pct'         => ['seller_share_pct', 'seller share', 'seller %'],
    'referral_share_pct'       => ['referral_share_pct', 'referral share', 'referral %'],
    'staff_share_pct'          => ['staff_share_pct', 'staff share', 'staff %'],
    'subscription_discount_pct'=> ['subscription_discount_pct', 'subscription discount', 'member discount'],
    /* which customer details the portal needs before it can be used — the thing
       a government portal actually has that a shopping item does not */
    'required_kyc'             => ['required_kyc', 'kyc', 'customer data', 'documents', 'required documents'],
];

function imp_norm($s) { return strtolower(trim(preg_replace('/\s+/', ' ', (string)$s))); }

/* ---------------------------------------------------------------------------
   IS THIS CATEGORY FREE?

   A government portal costs nothing, so a CSV for one has no business carrying
   price, discount and four share percentages — six columns that must all be
   left blank or set to zero, and which a person filling the sheet in has to
   read past every time. The same is true of any other category whose products
   are all free.

   The rule is read from the catalogue rather than hard-coded: Government
   Portals always is, and any other category counts as free once it holds
   products and not one of them carries a price. An empty category counts as
   paid, so the first product uploaded into it can still be priced.
   --------------------------------------------------------------------------- */
function imp_is_free($db, $cat_id) {
    static $cache = [];
    $cat_id = (int)$cat_id;
    if (isset($cache[$cat_id])) { return $cache[$cat_id]; }
    if ($cat_id === 1) { return $cache[$cat_id] = true; }
    try {
        $r = $db->select(
            "SELECT COUNT(*) AS n,
                    SUM(CASE WHEN GREATEST(COALESCE(price,0), COALESCE(discount_price,0)) > 0 THEN 1 ELSE 0 END) AS paid
               FROM seller_services WHERE category_id = ?", [$cat_id]);
        return $cache[$cat_id] = (!empty($r) && (int)$r[0]['n'] > 0 && (int)$r[0]['paid'] === 0);
    } catch (\Throwable $e) { return $cache[$cat_id] = false; }
}

/* The columns that only mean something where money changes hands. */
function imp_money_cols() {
    return ['price', 'discount_price', 'seller_share_pct', 'referral_share_pct',
            'staff_share_pct', 'subscription_discount_pct'];
}

/* the catalogue, needed by the sample file below and again further down */
$all_cats_early = [];
try { $all_cats_early = $db->select("SELECT id, title FROM service_categories ORDER BY display_order ASC, id ASC"); }
catch (\Throwable $e) { $all_cats_early = []; }

/* ---------------------------------------------------------------------------
   Sample CSV — shaped to the category it is for
   --------------------------------------------------------------------------- */
if (isset($_GET['template'])) {
    /* The sample matches the shelf you are uploading into. Handing somebody a
       Government Portals sheet with price, discount and four share columns on
       it — every one of them blank forever — is how a sheet gets filled in
       wrong. `cat` is the category the Bulk upload panel came from. */
    $t_cat  = isset($_GET['cat']) ? (int)$_GET['cat'] : 1;
    $t_free = imp_is_free($db, $t_cat);

    $t_name = 'category-' . $t_cat;
    foreach ($all_cats_early as $c) {
        if ((int)$c['id'] === $t_cat) {
            $t_name = strtolower(preg_replace('/[^a-z0-9]+/i', '_',
                html_entity_decode((string)$c['title'], ENT_QUOTES, 'UTF-8')));
            $t_name = trim((string)$t_name, '_');
            break;
        }
    }

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="wbmcz_' . $t_name . '_sample.csv"');
    $out = fopen('php://output', 'w');
    fprintf($out, chr(0xEF) . chr(0xBB) . chr(0xBF));

    if ($t_free) {
        /* Free shelf: name, what it is, where it goes, and what the customer
           has to hand over. No money columns at all. */
        fputcsv($out, ['title', 'description', 'web_url', 'app_url', 'tutorial_url',
                       'icon_class', 'color_class', 'sub_category', 'status', 'required_kyc']);
        fputcsv($out, ['Aadhaar Self Service Portal', 'Update address, download e-Aadhaar and check status',
                       'https://myaadhaar.uidai.gov.in/', '', 'https://youtu.be/xxxxxxxx',
                       'fa-id-card', 'color-1', '', '1', 'personal.full_name, personal.phone_number, identity.aadhaar_number']);
        fputcsv($out, ['PAN Card (NSDL)', 'Apply for a new PAN card or make corrections',
                       'https://www.onlineservices.nsdl.com/', '', '',
                       'fa-address-card', 'color-2', '', '1', 'personal.full_name, identity.pan_number']);
        fputcsv($out, ['Passport Seva', 'Fresh passport application and appointment booking',
                       'https://www.passportindia.gov.in/', '', '',
                       'fa-passport', 'color-3', '', '1', '']);
    } else {
        fputcsv($out, ['title', 'description', 'web_url', 'app_url', 'tutorial_url', 'icon_class', 'color_class',
                       'price', 'discount_price', 'sub_category', 'status', 'required_kyc',
                       'seller_share_pct', 'referral_share_pct', 'staff_share_pct', 'subscription_discount_pct']);
        fputcsv($out, ['Kotak Mahindra CSP Point', 'Banking correspondent point set-up with full support',
                       'https://example.com/apply', '', 'https://youtu.be/xxxxxxxx',
                       'fa-building-columns', 'color-1', '999', '699', '', '1',
                       'personal.full_name, personal.phone_number', '40', '5', '5', '10']);
        fputcsv($out, ['Recharge Distributor ID', 'Distributor login for mobile and DTH recharge',
                       'https://example.com/distributor', '', '',
                       'fa-mobile-screen', 'color-2', '499', '399', '', '1', '', '35', '5', '5', '10']);
        fputcsv($out, ['GST Registration', 'New GST number, filed and followed up for you',
                       'https://www.gst.gov.in/', '', '', 'fa-file-invoice', 'color-3',
                       '1499', '1199', '', '1', 'personal.full_name, identity.pan_number', '30', '5', '5', '5']);
    }
    fclose($out);
    exit;
}

/* ---------------------------------------------------------------------------
   Reference data
   --------------------------------------------------------------------------- */
$all_cats = $all_cats_early;
if (empty($all_cats)) { $all_cats = [['id' => 1, 'title' => 'Government Portals']]; }

$all_subs = [];
try { $all_subs = $db->select("SELECT id, category_id, title FROM agency_sub_categories ORDER BY title ASC"); } catch (\Throwable $e) {}

/* Every document key an admin can tick on a product, so a required_kyc column
   can be checked rather than trusted. If the catalogue cannot be read the
   column is accepted as written — better than refusing every row. */
$KYC_VALID = [];
try {
    require_once $WB_IMP_ROOT . '/includes/kyc_fields.php';
    if (function_exists('kycf_catalog')) {
        $__walk = function ($nodes) use (&$__walk, &$KYC_VALID) {
            foreach ((array)$nodes as $k => $n) {
                if (is_array($n)) {
                    if (!empty($n['key'])) { $KYC_VALID[(string)$n['key']] = true; }
                    elseif (is_string($k) && strpos($k, '.') !== false) { $KYC_VALID[$k] = true; }
                    $__walk($n);
                }
            }
        };
        $__walk(kycf_catalog($db));
    }
} catch (\Throwable $e) { $KYC_VALID = []; }

/* ---------------------------------------------------------------------------
   STEP 2 — parse the uploaded file (nothing is written yet)
   --------------------------------------------------------------------------- */
$preview     = null;   // ['rows' => [...], 'cat_id' => .., 'sub_id' => .., 'file' => ..]
$parse_error = '';

if (isset($_POST['preview_csv'])) {
    $cat_id = (int)($_POST['category_id'] ?? 1);
    $sub_id = (int)($_POST['sub_category_id'] ?? 0);

    if (empty($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
        $parse_error = 'No file was received. Please choose a .csv file and try again.';
    } else {
        $ext = strtolower(pathinfo($_FILES['csv_file']['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, ['csv', 'txt'], true)) {
            $parse_error = 'Only .csv files are supported. Save your Excel sheet as "CSV UTF-8" first.';
        } else {
            $fh = fopen($_FILES['csv_file']['tmp_name'], 'r');
            if (!$fh) {
                $parse_error = 'The file could not be opened.';
            } else {
                /* header row → column map */
                $header = fgetcsv($fh);
                if ($header && isset($header[0])) {
                    $header[0] = preg_replace('/^\xEF\xBB\xBF/', '', $header[0]);   // strip BOM
                }
                $map = [];
                if (is_array($header)) {
                    foreach ($header as $i => $h) {
                        $h = imp_norm($h);
                        foreach ($IMP_COLS as $key => $aliases) {
                            if (in_array($h, $aliases, true)) { $map[$key] = $i; break; }
                        }
                    }
                }
                if (!isset($map['title'])) {
                    $parse_error = 'A "title" column was not found in the first row. Download the sample CSV and use the same headers.';
                } else {
                    /* existing titles in this category — used for the duplicate verdict */
                    $existing = [];
                    try {
                        $rs = $db->select("SELECT title FROM seller_services WHERE category_id = ?", [$cat_id]);
                        foreach ($rs as $r) { $existing[imp_norm(html_entity_decode((string)$r['title'], ENT_QUOTES))] = true; }
                    } catch (\Throwable $e) {}

                    /* sub-category name → id, for this category */
                    $sub_by_name = [];
                    foreach ($all_subs as $sc) {
                        if ((int)$sc['category_id'] === $cat_id) {
                            $sub_by_name[imp_norm(html_entity_decode((string)$sc['title'], ENT_QUOTES))] = (int)$sc['id'];
                        }
                    }

                    $rows = []; $seen = []; $line = 1; $n_ok = 0; $n_dup = 0; $n_err = 0;
                    while (($data = fgetcsv($fh)) !== false) {
                        $line++;
                        if (count(array_filter($data, function ($v) { return trim((string)$v) !== ''; })) === 0) continue;   // blank line
                        if (count($rows) >= 2000) { break; }                                                                // hard ceiling

                        $get = function ($key) use ($map, $data) {
                            return isset($map[$key], $data[$map[$key]]) ? trim((string)$data[$map[$key]]) : '';
                        };

                        /* a free shelf ignores the money columns even when the
                           file carries them, so an old sheet still imports */
                        $is_free = imp_is_free($db, $cat_id);

                        $r = [
                            'line'         => $line,
                            'title'        => $get('title'),
                            'description'  => $get('description'),
                            'web_url'      => $get('web_url'),
                            'app_url'      => $get('app_url'),
                            'tutorial_url' => $get('tutorial_url'),
                            'icon_class'   => $get('icon_class'),
                            'color_class'  => $get('color_class'),
                            'price'        => $get('price'),
                            'discount_price' => $get('discount_price'),
                            'sub_raw'      => $get('sub_category'),
                            'status_raw'   => $get('status'),
                            's_seller'     => $get('seller_share_pct'),
                            's_ref'        => $get('referral_share_pct'),
                            's_staff'      => $get('staff_share_pct'),
                            's_sub'        => $get('subscription_discount_pct'),
                            'kyc_raw'      => $get('required_kyc'),
                        ];

                        /* ---- resolve + validate ---- */
                        $note = ''; $verdict = 'ok';
                        $key  = imp_norm($r['title']);

                        if ($r['title'] === '') {
                            $verdict = 'error'; $note = 'Title is empty';
                        } elseif (mb_strlen($r['title']) > 250) {
                            $verdict = 'error'; $note = 'Title is longer than 250 characters';
                        } elseif (isset($seen[$key])) {
                            $verdict = 'dup';   $note = 'Repeated in this file (line ' . $seen[$key] . ')';
                        } elseif (isset($existing[$key])) {
                            $verdict = 'dup';   $note = 'Already exists in this category';
                        }
                        $seen[$key] = $line;

                        if ($verdict === 'ok' && $r['web_url'] !== '' && !preg_match('~^https?://~i', $r['web_url'])) {
                            $r['web_url'] = 'https://' . ltrim($r['web_url'], '/');
                            $note = 'https:// added to the link';
                        }
                        if ($r['app_url'] !== '' && !preg_match('~^https?://~i', $r['app_url'])) {
                            $r['app_url'] = 'https://' . ltrim($r['app_url'], '/');
                        }
                        if ($r['tutorial_url'] !== '' && !preg_match('~^https?://~i', $r['tutorial_url'])) {
                            $r['tutorial_url'] = 'https://' . ltrim($r['tutorial_url'], '/');
                        }

                        /* sub-category: a name, an id, or the page default */
                        $sub = $sub_id;
                        if ($r['sub_raw'] !== '') {
                            if (ctype_digit($r['sub_raw'])) { $sub = (int)$r['sub_raw']; }
                            elseif (isset($sub_by_name[imp_norm($r['sub_raw'])])) { $sub = $sub_by_name[imp_norm($r['sub_raw'])]; }
                            else { $note = trim($note . ' · sub-category "' . $r['sub_raw'] . '" not found, page default used', ' ·'); }
                        }
                        $r['sub_id'] = $sub;

                        /* prices — a free shelf is free whatever the file says */
                        $price = (float)preg_replace('/[^0-9.\-]/', '', $r['price']);
                        $disc  = (float)preg_replace('/[^0-9.\-]/', '', $r['discount_price']);
                        if ($is_free) { $price = 0.0; $disc = 0.0; }
                        if ($price < 0) $price = 0.0;
                        if ($disc  < 0) $disc  = 0.0;
                        if ($disc > 0 && $price > 0 && $disc > $price) {
                            $verdict = ($verdict === 'ok') ? 'error' : $verdict;
                            $note = 'Discount price is higher than the price';
                        }
                        $r['price_f'] = $price; $r['disc_f'] = $disc;

                        /* icon / image */
                        $icon = $r['icon_class'];
                        $r['is_img'] = (strpos($icon, 'http') === 0 || strpos($icon, 'uploads/') === 0) ? 1 : 0;
                        if ($icon === '') { $icon = 'fa-globe'; }
                        $r['icon_f']  = $icon;
                        $r['color_f'] = $r['color_class'] !== '' ? $r['color_class'] : 'color-1';

                        /* status */
                        $st = imp_norm($r['status_raw']);
                        $r['status_f'] = in_array($st, ['0', 'inactive', 'no', 'off', 'draft', 'pending'], true) ? 0 : 1;

                        /* what the customer has to hand over. Unknown keys are
                           dropped with a note rather than failing the row — a
                           typo in one document name should not lose the portal. */
                        $kyc_keys = [];
                        if ($r['kyc_raw'] !== '') {
                            $bad = [];
                            foreach (preg_split('/[,;|]+/', $r['kyc_raw']) as $k) {
                                $k = trim((string)$k);
                                if ($k === '') { continue; }
                                if (!empty($KYC_VALID) && !isset($KYC_VALID[$k])) { $bad[] = $k; continue; }
                                $kyc_keys[] = $k;
                            }
                            if (!empty($bad)) {
                                $note = trim($note . ' · not a known document: ' . implode(', ', array_slice($bad, 0, 3)), ' ·');
                            }
                        }
                        $r['kyc_f'] = implode(',', array_unique($kyc_keys));

                        /* share percentages */
                        $p_sel = max(0, (float)preg_replace('/[^0-9.]/', '', $r['s_seller']));
                        $p_ref = max(0, (float)preg_replace('/[^0-9.]/', '', $r['s_ref']));
                        $p_stf = max(0, (float)preg_replace('/[^0-9.]/', '', $r['s_staff']));
                        $p_sub = max(0, (float)preg_replace('/[^0-9.]/', '', $r['s_sub']));
                        if ($is_free) { $p_sel = $p_ref = $p_stf = $p_sub = 0.0; }
                        if (($p_sel + $p_ref + $p_stf + $p_sub) > 100) {
                            $verdict = ($verdict === 'ok') ? 'error' : $verdict;
                            $note = 'Share percentages add up to more than 100%';
                        }
                        $r['p_sel'] = $p_sel; $r['p_ref'] = $p_ref; $r['p_stf'] = $p_stf; $r['p_sub'] = $p_sub;
                        $r['p_com'] = round(max(0, 100 - ($p_sel + $p_ref + $p_stf + $p_sub)), 2);

                        $r['verdict'] = $verdict;
                        $r['note']    = $note;
                        if ($verdict === 'ok') $n_ok++; elseif ($verdict === 'dup') $n_dup++; else $n_err++;

                        $rows[] = $r;
                    }
                    fclose($fh);

                    if (empty($rows)) {
                        $parse_error = 'The file has a header row but no data rows.';
                    } else {
                        $preview = [
                            'rows' => $rows, 'cat_id' => $cat_id, 'sub_id' => $sub_id,
                            'file' => $_FILES['csv_file']['name'],
                            'ok' => $n_ok, 'dup' => $n_dup, 'err' => $n_err,
                        ];
                    }
                }
            }
        }
    }
    if ($parse_error !== '') { $error_msg = $parse_error; }
}

/* ---------------------------------------------------------------------------
   STEP 3 — write the approved rows
   --------------------------------------------------------------------------- */
if (isset($_POST['confirm_import'])) {
    $cat_id  = (int)($_POST['category_id'] ?? 1);
    $payload = json_decode(base64_decode((string)($_POST['payload'] ?? '')), true);
    $keep_dup = !empty($_POST['include_duplicates']);

    if (!is_array($payload) || empty($payload)) {
        $_SESSION['flash_error'] = 'Nothing to import — the preview had expired. Please upload the file again.';
        redirect('service_import.php');
    }

    $made = 0; $skipped = 0; $failed = 0;
    foreach ($payload as $r) {
        $verdict = $r['verdict'] ?? 'ok';
        if ($verdict === 'error') { $skipped++; continue; }
        if ($verdict === 'dup' && !$keep_dup) { $skipped++; continue; }

        try {
            $new_id = $db->insert(
                "INSERT INTO seller_services
                 (seller_id, category_id, sub_category_id, title, description, price, discount_price,
                  is_img, icon_class, color_class, web_url, app_url, tutorial_url, status, required_kyc)
                 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
                [
                    $user_id, $cat_id, (int)($r['sub_id'] ?? 0),
                    sanitize($r['title'] ?? ''), sanitize($r['description'] ?? ''),
                    (float)($r['price_f'] ?? 0), (float)($r['disc_f'] ?? 0),
                    (int)($r['is_img'] ?? 0), sanitize($r['icon_f'] ?? 'fa-globe'),
                    sanitize($r['color_f'] ?? 'color-1'), sanitize($r['web_url'] ?? ''),
                    sanitize($r['app_url'] ?? ''), sanitize($r['tutorial_url'] ?? ''),
                    (int)($r['status_f'] ?? 1),
                    /* the document keys, already checked against the catalogue at
                       preview time — an empty string means "ask for nothing" */
                    substr((string)($r['kyc_f'] ?? ''), 0, 255),
                ]
            );

            /* share split — only written when the CSV actually carried numbers */
            if ($new_id && (($r['p_sel'] ?? 0) + ($r['p_ref'] ?? 0) + ($r['p_stf'] ?? 0) + ($r['p_sub'] ?? 0)) > 0) {
                try {
                    $db->insert("UPDATE seller_services
                                 SET share_mode = 'percent', seller_share_pct = ?, referral_share_pct = ?,
                                     staff_share_pct = ?, subscription_discount_pct = ?, company_share_pct = ?
                                 WHERE id = ?",
                        [(float)$r['p_sel'], (float)$r['p_ref'], (float)$r['p_stf'], (float)$r['p_sub'], (float)$r['p_com'], (int)$new_id]);
                } catch (\Throwable $e) {}
            }

            if ($new_id) $made++; else $failed++;
        } catch (\Throwable $e) { $failed++; }
    }

    $_SESSION['flash_success'] = "Import finished — $made added" . ($skipped ? ", $skipped skipped" : '') . ($failed ? ", $failed failed" : '') . '.';
    redirect($IMP_BACK !== '' ? $IMP_BACK : 'service_import.php');
}

/* recent imports by this admin, for the panel at the bottom */
$recent = [];
try {
    $recent = $db->select(
        "SELECT ss.id, ss.title, ss.status, ss.created_at, sc.title AS cat_name
         FROM seller_services ss
         LEFT JOIN service_categories sc ON ss.category_id = sc.id
         WHERE ss.seller_id = ? ORDER BY ss.id DESC LIMIT 12", [$user_id]);
} catch (\Throwable $e) {}

$company_logo = getSetting('company_logo', '../assets/images/logo.png');
$sel_cat = (int)($preview['cat_id'] ?? ($_POST['category_id'] ?? 1));
$sel_sub = (int)($preview['sub_id'] ?? 0);
?>
<!DOCTYPE html>
<html lang="<?php echo $current_lang; ?>">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bulk Import - Admin Panel</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
    <style>
        body { font-family:'Inter',sans-serif; }
        .imp-drop { border:2px dashed #cbd5e1; border-radius:1rem; background:#f8fafc; padding:1.75rem 1rem;
                    text-align:center; transition:.15s; cursor:pointer; }
        .imp-drop:hover { border-color:#6366f1; background:#eef2ff; }
        .imp-step { display:flex; align-items:center; gap:.55rem; font-size:11px; font-weight:800;
                    text-transform:uppercase; letter-spacing:.08em; color:#94a3b8; }
        .imp-step b { width:22px; height:22px; border-radius:50%; background:#e2e8f0; color:#64748b;
                      display:flex; align-items:center; justify-content:center; font-size:11px; }
        .imp-step.on { color:#4338ca; } .imp-step.on b { background:#4f46e5; color:#fff; }
        .imp-tbl { width:100%; border-collapse:collapse; font-size:11.5px; }
        .imp-tbl th { background:#f8fafc; text-align:left; padding:.55rem .6rem; font-size:9.5px; font-weight:900;
                      text-transform:uppercase; letter-spacing:.06em; color:#94a3b8; border-bottom:1px solid #e2e8f0;
                      position:sticky; top:0; z-index:1; }
        .imp-tbl td { padding:.5rem .6rem; border-bottom:1px solid #f1f5f9; color:#334155; vertical-align:top; }
        .imp-tbl tr.err td { background:#fff1f2; }
        .imp-tbl tr.dup td { background:#fffbeb; }
        .imp-pill { display:inline-flex; align-items:center; gap:.3rem; padding:.15rem .5rem; border-radius:999px;
                    font-size:9.5px; font-weight:900; text-transform:uppercase; letter-spacing:.05em; }
        .imp-ok  { background:#dcfce7; color:#15803d; }
        .imp-dp  { background:#fef3c7; color:#b45309; }
        .imp-er  { background:#ffe4e6; color:#be123c; }
        .imp-code { font-family:ui-monospace,'Courier New',monospace; font-size:10.5px; color:#475569;
                    background:#f1f5f9; padding:.1rem .35rem; border-radius:.35rem; }
    </style>
</head>
<body class="bg-gray-50" x-data="{ sidebarOpen: window.innerWidth >= 768, fileName: '' }">

    <div class="flex h-screen overflow-hidden">

        <?php include __DIR__ . '/includes/sidebar.php'; ?>

        <div class="flex-1 flex flex-col min-w-0 bg-gray-100 overflow-hidden">
            <header class="h-20 bg-white text-slate-800 flex items-center justify-between px-4 shadow-sm border-b border-gray-200 z-40 relative">
                <div class="flex items-center">
                    <button @click="sidebarOpen = !sidebarOpen" class="p-2 mr-3 text-slate-500 hover:text-emerald-600 rounded-lg"><i class="fas fa-bars text-xl"></i></button>
                    <h2 class="text-xl font-bold hidden md:block text-slate-800">Bulk Import</h2>
                </div>
                <a href="service_import.php?template=1&amp;cat=<?php echo (int)$sel_cat; ?>" class="al-btn al-btn-csv"><i class="fas fa-download"></i> Sample CSV</a>
            </header>

            <main class="flex-1 overflow-y-auto p-4 md:p-6">

                <?php echo alist_styles(); ?>

                <?php if (isset($success_msg)): ?>
                <div class="mb-5 bg-emerald-50 border border-emerald-200 text-emerald-700 px-4 py-3 rounded-xl flex items-center shadow-sm">
                    <i class="fas fa-check-circle mr-2"></i><span class="font-medium"><?php echo htmlspecialchars($success_msg); ?></span>
                </div>
                <?php endif; ?>
                <?php if (isset($error_msg)): ?>
                <div class="mb-5 bg-rose-50 border border-rose-200 text-rose-700 px-4 py-3 rounded-xl flex items-center shadow-sm">
                    <i class="fas fa-triangle-exclamation mr-2"></i><span class="font-medium"><?php echo htmlspecialchars($error_msg); ?></span>
                </div>
                <?php endif; ?>

                <!-- steps -->
                <div class="flex flex-wrap items-center gap-5 mb-5">
                    <div class="imp-step <?php echo $preview ? '' : 'on'; ?>"><b>1</b> Choose file</div>
                    <i class="fas fa-chevron-right text-[9px] text-slate-300"></i>
                    <div class="imp-step <?php echo $preview ? 'on' : ''; ?>"><b>2</b> Check the preview</div>
                    <i class="fas fa-chevron-right text-[9px] text-slate-300"></i>
                    <div class="imp-step"><b>3</b> Import</div>
                </div>

                <?php if (!$preview): ?>
                <!-- ================= STEP 1 ================= -->
                <div class="grid grid-cols-1 xl:grid-cols-3 gap-5">

                    <form method="POST" enctype="multipart/form-data" class="al-panel p-5 xl:col-span-2">
                        <?php echo $IMP_HIDDEN; ?>
                        <h3 class="text-base font-extrabold text-slate-800 mb-1"><i class="fas fa-file-import text-indigo-500 mr-2"></i>Upload a CSV</h3>
                        <p class="text-xs text-slate-500 mb-5">Every row becomes one portal / service in the category you pick below. Nothing is saved until you have seen the preview.</p>

                        <div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
                            <div>
                                <label class="al-l">Category</label>
                                <?php if ($IMP_LOCK):
                                    $__ct = '';
                                    foreach ($all_cats as $c) { if ((int)$c['id'] === $sel_cat) { $__ct = (string)$c['title']; break; } } ?>
                                    <input type="hidden" name="category_id" value="<?php echo (int)$sel_cat; ?>">
                                    <div class="al-f bg-slate-50 font-bold text-slate-700 flex items-center gap-2">
                                        <i class="fas fa-lock text-[11px] text-slate-400"></i><?php echo esc($__ct); ?>
                                    </div>
                                    <p class="text-[10px] text-slate-400 mt-1">Fixed — you started this upload from that page.</p>
                                <?php else: ?>
                                <select name="category_id" class="al-f" x-ref="cat" @change="$refs.sub.value=''">
                                    <?php foreach ($all_cats as $c): ?>
                                        <option value="<?php echo (int)$c['id']; ?>" <?php echo ((int)$c['id'] === $sel_cat) ? 'selected' : ''; ?>>
                                            <?php echo esc($c['title']); ?>
                                        </option>
                                    <?php endforeach; ?>
                                </select>
                                <p class="text-[10px] text-slate-400 mt-1">A free category ignores any price or share column in the file.</p>
                                <?php endif; ?>
                            </div>
                            <div>
                                <label class="al-l">Default sub-category <span class="text-slate-400 normal-case font-medium">(optional)</span></label>
                                <select name="sub_category_id" class="al-f" x-ref="sub">
                                    <option value="0">— none —</option>
                                    <?php foreach ($all_subs as $sc): ?>
                                        <option value="<?php echo (int)$sc['id']; ?>"><?php echo esc($sc['title']); ?></option>
                                    <?php endforeach; ?>
                                </select>
                                <p class="text-[10px] text-slate-400 mt-1">A <span class="imp-code">sub_category</span> column in the file overrides this.</p>
                            </div>
                        </div>

                        <label class="imp-drop block" for="csvFile">
                            <i class="fas fa-cloud-arrow-up text-3xl text-indigo-400 mb-2"></i>
                            <p class="text-sm font-bold text-slate-700" x-text="fileName || 'Click to choose a .csv file'"></p>
                            <p class="text-[11px] text-slate-400 mt-1">Up to 2000 rows per file · UTF-8 CSV</p>
                            <input id="csvFile" type="file" name="csv_file" accept=".csv,text/csv" class="hidden"
                                   @change="fileName = $event.target.files.length ? $event.target.files[0].name : ''">
                        </label>

                        <div class="flex flex-wrap gap-2 mt-5">
                            <button type="submit" name="preview_csv" value="1" class="al-btn al-btn-apply"><i class="fas fa-eye"></i> Preview rows</button>
                            <a href="service_import.php?template=1&amp;cat=<?php echo (int)$sel_cat; ?>" class="al-btn al-btn-ghost"><i class="fas fa-file-csv"></i> Download sample</a>
                        </div>
                    </form>

                    <div class="al-panel p-5">
                        <h3 class="text-sm font-extrabold text-slate-800 mb-3"><i class="fas fa-circle-info text-slate-400 mr-1.5"></i>Column reference</h3>
                        <ul class="text-[11.5px] text-slate-600 space-y-2">
                            <li><span class="imp-code">title</span> <b class="text-rose-500">required</b> — the portal name</li>
                            <li><span class="imp-code">description</span> short details</li>
                            <li><span class="imp-code">web_url</span> portal link (https:// is added if missing)</li>
                            <li><span class="imp-code">app_url</span> · <span class="imp-code">tutorial_url</span></li>
                            <li><span class="imp-code">icon_class</span> a Font Awesome class such as <i>fa-id-card</i>, or a full image URL</li>
                            <li><span class="imp-code">color_class</span> color-1 … color-8</li>
                            <li><span class="imp-code">sub_category</span> name or id</li>
                            <li><span class="imp-code">status</span> 1 = live, 0 = hidden</li>
                            <li><span class="imp-code">required_kyc</span> which details the customer must give, comma separated
                                (for example <i>personal.full_name, identity.aadhaar_number</i>). Leave it blank to ask for nothing.</li>
                            <?php if (imp_is_free($db, $sel_cat)): ?>
                            <li class="text-emerald-700 bg-emerald-50 border border-emerald-100 rounded-lg px-2.5 py-2">
                                This category is free, so <span class="imp-code">price</span>,
                                <span class="imp-code">discount_price</span> and the four share columns are not in its sample
                                and are ignored if your file has them.
                            </li>
                            <?php else: ?>
                            <li><span class="imp-code">price</span> · <span class="imp-code">discount_price</span></li>
                            <li><span class="imp-code">seller_share_pct</span>, <span class="imp-code">referral_share_pct</span>,
                                <span class="imp-code">staff_share_pct</span>, <span class="imp-code">subscription_discount_pct</span> —
                                optional; whatever is left over becomes the company share</li>
                            <?php endif; ?>
                        </ul>
                        <div class="mt-4 text-[11px] bg-indigo-50 border border-indigo-100 text-indigo-700 rounded-xl p-3 leading-relaxed">
                            Imported rows are owned by <b>you</b> (<?php echo esc($me_name); ?>) and go
                            live immediately. A row whose title already exists in the chosen category is marked as a duplicate and
                            skipped unless you tick the box on the preview screen.
                        </div>
                    </div>
                </div>

                <?php if (!empty($recent)): ?>
                <div class="al-panel mt-5 overflow-hidden">
                    <div class="px-5 py-3 border-b border-slate-100 flex items-center justify-between">
                        <h3 class="text-sm font-extrabold text-slate-800"><i class="fas fa-clock-rotate-left text-slate-400 mr-1.5"></i>Recently added by you</h3>
                        <a href="product_management.php" class="text-[11px] font-bold text-indigo-600">Open Product Management <i class="fas fa-arrow-right ml-1"></i></a>
                    </div>
                    <div class="overflow-x-auto">
                        <table class="imp-tbl">
                            <thead><tr><th>#</th><th>Title</th><th>Category</th><th>Status</th><th>Added</th></tr></thead>
                            <tbody>
                            <?php foreach ($recent as $r): ?>
                                <tr>
                                    <td><?php echo (int)$r['id']; ?></td>
                                    <td class="font-bold text-slate-700"><?php echo esc($r['title']); ?></td>
                                    <td><?php echo esc($r['cat_name']); ?></td>
                                    <td><?php echo ((int)$r['status'] === 1)
                                        ? '<span class="imp-pill imp-ok">Live</span>'
                                        : '<span class="imp-pill imp-dp">Hidden</span>'; ?></td>
                                    <td class="text-slate-400"><?php echo !empty($r['created_at']) ? date('d M Y', strtotime($r['created_at'])) : '—'; ?></td>
                                </tr>
                            <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
                <?php endif; ?>

                <?php else: ?>
                <!-- ================= STEP 2 — PREVIEW ================= -->
                <?php
                    $cat_title = 'Category #' . $preview['cat_id'];
                    foreach ($all_cats as $c) { if ((int)$c['id'] === (int)$preview['cat_id']) { $cat_title = $c['title']; break; } }
                    $payload = base64_encode(json_encode($preview['rows']));
                    $pv_free = imp_is_free($db, (int)$preview['cat_id']);
                ?>
                <?php echo alist_stats([
                    ['label' => 'Rows in file', 'value' => count($preview['rows']), 'icon' => 'fa-list',           'colour' => 'slate'],
                    ['label' => 'Ready',        'value' => $preview['ok'],          'icon' => 'fa-circle-check',   'colour' => 'emerald'],
                    ['label' => 'Duplicates',   'value' => $preview['dup'],         'icon' => 'fa-clone',          'colour' => 'amber'],
                    ['label' => 'Errors',       'value' => $preview['err'],         'icon' => 'fa-circle-xmark',   'colour' => 'rose'],
                    ['label' => 'Category',     'value' => esc($cat_title),         'icon' => 'fa-layer-group',    'colour' => 'indigo'],
                    ['label' => 'File',         'value' => '<span class="text-[11px]">' . esc($preview['file']) . '</span>', 'icon' => 'fa-file-csv', 'colour' => 'sky'],
                ]); ?>

                <form method="POST" class="al-panel overflow-hidden">
                    <input type="hidden" name="category_id" value="<?php echo (int)$preview['cat_id']; ?>">
                    <input type="hidden" name="payload" value="<?php echo $payload; ?>">
                    <?php echo $IMP_HIDDEN; ?>

                    <div class="px-5 py-4 border-b border-slate-100 flex flex-wrap items-center justify-between gap-3">
                        <div>
                            <h3 class="text-base font-extrabold text-slate-800">Check before importing</h3>
                            <p class="text-xs text-slate-500 mt-0.5">
                                Only the <b class="text-emerald-600"><?php echo $preview['ok']; ?> ready</b> row(s) will be added.
                                Rows marked <b class="text-rose-600">error</b> are never imported.
                            </p>
                        </div>
                        <div class="flex flex-wrap items-center gap-2">
                            <?php if ($preview['dup'] > 0): ?>
                            <label class="flex items-center gap-2 text-[11.5px] font-bold text-amber-700 bg-amber-50 border border-amber-200 rounded-xl px-3 py-2">
                                <input type="checkbox" name="include_duplicates" value="1" class="rounded">
                                Import the <?php echo $preview['dup']; ?> duplicate row(s) too
                            </label>
                            <?php endif; ?>
                            <a href="service_import.php" class="al-btn al-btn-ghost"><i class="fas fa-rotate-left"></i> Start over</a>
                            <button type="submit" name="confirm_import" value="1" class="al-btn al-btn-apply"
                                    <?php echo ($preview['ok'] === 0 && $preview['dup'] === 0) ? 'disabled style="opacity:.5;cursor:not-allowed"' : ''; ?>>
                                <i class="fas fa-cloud-arrow-up"></i> Import now
                            </button>
                        </div>
                    </div>

                    <div class="overflow-x-auto" style="max-height:62vh">
                        <table class="imp-tbl">
                            <thead>
                                <tr>
                                    <th>Line</th><th>Verdict</th><th>Title</th><th>Link</th>
                                    <th>Icon</th><?php if (!$pv_free): ?><th>Price</th><?php endif; ?>
                                    <th>Customer data</th><th>Sub-cat</th><th>Status</th><th>Note</th>
                                </tr>
                            </thead>
                            <tbody>
                            <?php foreach ($preview['rows'] as $r):
                                $cls = $r['verdict'] === 'error' ? 'err' : ($r['verdict'] === 'dup' ? 'dup' : '');
                                $pill = $r['verdict'] === 'error' ? '<span class="imp-pill imp-er">Error</span>'
                                      : ($r['verdict'] === 'dup' ? '<span class="imp-pill imp-dp">Duplicate</span>'
                                      : '<span class="imp-pill imp-ok">Ready</span>');
                            ?>
                                <tr class="<?php echo $cls; ?>">
                                    <td class="text-slate-400"><?php echo (int)$r['line']; ?></td>
                                    <td><?php echo $pill; ?></td>
                                    <td class="font-bold text-slate-700" style="max-width:220px"><?php echo esc($r['title']); ?></td>
                                    <td style="max-width:200px;word-break:break-all">
                                        <?php echo $r['web_url'] !== '' ? '<span class="imp-code">' . esc($r['web_url']) . '</span>' : '<span class="text-slate-300">—</span>'; ?>
                                    </td>
                                    <td><span class="imp-code"><?php echo esc($r['icon_f']); ?></span></td>
                                    <?php if (!$pv_free): ?>
                                    <td><?php echo $r['price_f'] > 0 ? '₹' . number_format($r['price_f'], 2) : '<span class="text-emerald-600 font-bold">Free</span>'; ?></td>
                                    <?php endif; ?>
                                    <td style="max-width:180px">
                                        <?php $__k = (string)($r['kyc_f'] ?? '');
                                              echo $__k !== ''
                                                ? '<span class="imp-code">' . esc(str_replace(',', ', ', $__k)) . '</span>'
                                                : '<span class="text-slate-300">none</span>'; ?>
                                    </td>
                                    <td><?php echo (int)$r['sub_id'] > 0 ? (int)$r['sub_id'] : '<span class="text-slate-300">—</span>'; ?></td>
                                    <td><?php echo (int)$r['status_f'] === 1 ? 'Live' : 'Hidden'; ?></td>
                                    <td class="text-slate-500" style="max-width:230px"><?php echo esc($r['note']); ?></td>
                                </tr>
                            <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                </form>
                <?php endif; ?>

            </main>
        </div>
    </div>
</body>
</html>
