<?php
declare(strict_types=1);
require __DIR__ . '/../../includes/bootstrap.php';

require_admin_login();

// ensure schema supports categories + parent relation
try {
  $cols = pdo()->query("SHOW COLUMNS FROM skills")->fetchAll(PDO::FETCH_COLUMN, 0);
  $alter = [];
  if (!in_array('category', $cols, true))  $alter[] = "ADD COLUMN category VARCHAR(32) NOT NULL DEFAULT 'language'";
  if (!in_array('parent_id', $cols, true)) $alter[] = "ADD COLUMN parent_id INT NULL DEFAULT NULL";
  if ($alter) {
    pdo()->exec("ALTER TABLE skills " . implode(", ", $alter));
  }
} catch (Throwable $e) {}

// ensure pivot table for multi-language frameworks
try {
  pdo()->exec("
    CREATE TABLE IF NOT EXISTS skill_links (
      id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      framework_id INT NOT NULL,
      language_id INT NOT NULL,
      UNIQUE KEY uniq_fw_lang (framework_id, language_id),
      KEY idx_fw (framework_id),
      KEY idx_lang (language_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  ");
  // seed from legacy parent_id if any exist
  pdo()->exec("
    INSERT IGNORE INTO skill_links (framework_id, language_id)
    SELECT id AS framework_id, parent_id AS language_id
    FROM skills
    WHERE category='framework' AND parent_id IS NOT NULL AND parent_id > 0
  ");
} catch (Throwable $e) {}

if (empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(32));
function csrf_ok($t): bool { return is_string($t) && hash_equals($_SESSION['csrf'], $t); }

if (!function_exists('flash_set')) {
  function flash_set(string $type, string $msg): void { $_SESSION['_flash'] = ['type'=>$type,'msg'=>$msg]; }
}
if (!function_exists('flash_get')) {
  function flash_get(): ?array { $f=$_SESSION['_flash']??null; unset($_SESSION['_flash']); return is_array($f)?$f:null; }
}
$f = flash_get();
$allowedCategories = ['language','framework'];

function normalize_ids(array $ids): array {
  $out = [];
  foreach ($ids as $v) {
    $v = (int)$v;
    if ($v > 0) $out[$v] = $v;
  }
  return array_values($out);
}

function fetch_language_ids(): array {
  try {
    $ids = pdo()->query("SELECT id FROM skills WHERE category='language'")->fetchAll(PDO::FETCH_COLUMN, 0);
    return array_map('intval', $ids ?: []);
  } catch (Throwable $e) {
    return [];
  }
}

function sync_framework_languages(int $frameworkId, array $languageIds, array $validLanguageIds): void {
  $validSet = array_flip($validLanguageIds);
  $languageIds = array_values(array_filter(array_unique(array_map('intval', $languageIds)), function ($id) use ($validSet) {
    return $id > 0 && isset($validSet[$id]);
  }));

  pdo()->prepare("DELETE FROM skill_links WHERE framework_id=?")->execute([$frameworkId]);
  if (!$languageIds) return;

  $ins = pdo()->prepare("INSERT IGNORE INTO skill_links (framework_id, language_id) VALUES (?, ?)");
  foreach ($languageIds as $lid) {
    $ins->execute([$frameworkId, $lid]);
  }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if (!csrf_ok((string)($_POST['csrf'] ?? ''))) {
    flash_set('danger', 'Bad CSRF token.');
    header('Location: /public/admin/skills.php'); exit;
  }

  // DELETE (handled first, so it never falls into update_many)
  if (isset($_POST['delete_id'])) {
    $id = (int)($_POST['delete_id'] ?? 0);
    if ($id > 0) {
      pdo()->prepare("UPDATE skills SET parent_id=NULL WHERE parent_id=?")->execute([$id]);
      pdo()->prepare("DELETE FROM skill_links WHERE framework_id=? OR language_id=?")->execute([$id, $id]);
      pdo()->prepare("DELETE FROM skills WHERE id=?")->execute([$id]);
      flash_set('success', 'Skill deleted.');
    }
    header('Location: /public/admin/skills.php'); exit;
  }

  $action = (string)($_POST['action'] ?? '');

  if ($action === 'create') {
    $label = trim((string)($_POST['label'] ?? ''));
    $icon  = trim((string)($_POST['icon'] ?? 'ri-code-s-slash-line'));
    $level = max(0, min(100, (int)($_POST['level'] ?? 0)));
    $sort  = (int)($_POST['sort_order'] ?? 0);
    $category = strtolower(trim((string)($_POST['category'] ?? 'language')));
    if (!in_array($category, $allowedCategories, true)) $category = 'language';
    $parentIds = $category === 'framework' ? normalize_ids((array)($_POST['parent_id_new'] ?? [])) : [];
    $validLanguageIds = $category === 'framework' ? fetch_language_ids() : [];
    if ($parentIds && $validLanguageIds) {
      $parentIds = array_values(array_intersect($parentIds, $validLanguageIds));
    }

    if ($label === '') {
      flash_set('danger', 'Label is required.');
    } else {
      if ($category === 'framework') {
        if (!$parentIds) {
          flash_set('danger', 'Select one or more parent languages for this framework.');
          header('Location: /public/admin/skills.php'); exit;
        }
      } else {
        $parentIds = [];
      }

      $primaryParent = ($category === 'framework' && $parentIds) ? (int)$parentIds[0] : null;

      pdo()->prepare("INSERT INTO skills (label, icon, level, sort_order, category, parent_id) VALUES (?,?,?,?,?,?)")
          ->execute([$label, $icon, $level, $sort, $category, $primaryParent]);
      $newId = (int)pdo()->lastInsertId();

      if ($category === 'framework' && $newId > 0) {
        sync_framework_languages($newId, $parentIds, $validLanguageIds);
      }
      flash_set('success', 'Skill added.');
    }
    header('Location: /public/admin/skills.php'); exit;
  }

  if ($action === 'update_many') {
    $ids = $_POST['id'] ?? [];
    $categoriesMap = [];
    foreach ($ids as $i => $idRaw) {
      $cid = (int)$idRaw;
      $catRaw = strtolower(trim((string)($_POST['category'][$i] ?? 'language')));
      $categoriesMap[$cid] = in_array($catRaw, $allowedCategories, true) ? $catRaw : 'language';
    }
    // use DB-backed language ids to avoid losing links if a row is flipped to framework
    $validLanguageIds = fetch_language_ids();
    $parentSelections = (array)($_POST['parent_id'] ?? []);

    foreach ($ids as $i => $idRaw) {
      $id = (int)$idRaw;
      if ($id <= 0) continue;

      $label = trim((string)($_POST['label'][$i] ?? ''));
      $icon  = trim((string)($_POST['icon'][$i] ?? 'ri-code-s-slash-line'));
      $level = max(0, min(100, (int)($_POST['level'][$i] ?? 0)));
      $sort  = (int)($_POST['sort_order'][$i] ?? 0);
      $category = $categoriesMap[$id] ?? 'language';
      $selectedParents = ($category === 'framework') ? normalize_ids((array)($parentSelections[$id] ?? [])) : [];
      if ($selectedParents && $validLanguageIds) {
        $selectedParents = array_values(array_intersect($selectedParents, $validLanguageIds));
      }
      $primaryParent = ($category === 'framework' && $selectedParents) ? (int)$selectedParents[0] : null;

      pdo()->prepare("UPDATE skills SET label=?, icon=?, level=?, sort_order=?, category=?, parent_id=? WHERE id=?")
          ->execute([$label, $icon, $level, $sort, $category, $primaryParent, $id]);

      if ($category === 'framework') {
        sync_framework_languages($id, $selectedParents, $validLanguageIds);
        // if this was previously a language, clear stale links where it was used as a parent
        pdo()->prepare("DELETE FROM skill_links WHERE language_id=? AND framework_id!=?")->execute([$id, $id]);
      } else {
        // if it is (or is now) a language, only remove links where it was the framework
        pdo()->prepare("DELETE FROM skill_links WHERE framework_id=?")->execute([$id]);
      }
    }
    flash_set('success', 'Skills updated.');
    header('Location: /public/admin/skills.php'); exit;
  }
}

$skills = [];
try {
  $skills = pdo()->query("SELECT id,label,icon,level,sort_order,category,parent_id FROM skills ORDER BY (category='language') DESC, sort_order ASC, id ASC")->fetchAll() ?: [];
} catch (Throwable $e) {}
$skillLinks = [];
try {
  $skillLinks = pdo()->query("SELECT framework_id, language_id FROM skill_links")->fetchAll(PDO::FETCH_ASSOC) ?: [];
} catch (Throwable $e) {}
$frameworkParentMap = [];
foreach ($skillLinks as $link) {
  $fw = (int)($link['framework_id'] ?? 0);
  $lang = (int)($link['language_id'] ?? 0);
  if ($fw > 0 && $lang > 0) {
    if (!isset($frameworkParentMap[$fw])) $frameworkParentMap[$fw] = [];
    $frameworkParentMap[$fw][$lang] = $lang;
  }
}

$languageOptions = array_values(array_filter($skills, function ($s) {
  return strtolower((string)($s['category'] ?? 'language')) === 'language';
}));
$languageLabelMap = [];
foreach ($languageOptions as $lang) {
  $languageLabelMap[(int)$lang['id']] = (string)$lang['label'];
}
// fallback to legacy parent_id if no links saved yet
foreach ($skills as $s) {
  $cat = strtolower((string)($s['category'] ?? 'language'));
  if ($cat !== 'framework') continue;
  $fwId = (int)($s['id'] ?? 0);
  $pid = (int)($s['parent_id'] ?? 0);
  if ($fwId > 0 && $pid > 0 && empty($frameworkParentMap[$fwId])) {
    $frameworkParentMap[$fwId][$pid] = $pid;
  }
}

$frameworkParentMap = array_map('array_values', $frameworkParentMap);

$openNew = isset($_GET['new']);
?>
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Skills • Admin</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="stylesheet" href="/public/css/admin.css">
  <style>
    .lvl{width:120px}
    body { font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif; }
    .table-responsive { overflow: visible; }
    .parent-wrap { position: relative; }
    .new-skill-card { position: relative; z-index: 50; overflow: visible; }
    .parent-picker-btn {
      background: linear-gradient(120deg, rgba(255,255,255,.05), rgba(139,92,246,.08));
      border: 1px solid rgba(255,255,255,.08);
      color: #f8fafc;
      transition: all .18s ease;
    }
    .parent-picker-btn:hover {
      border-color: rgba(167,139,250,.6);
      box-shadow: 0 12px 28px rgba(0,0,0,.2);
    }
    .parent-summary {
      font-weight: 600;
      letter-spacing: 0.01em;
    }
    .parent-menu {
      max-height: 260px;
      overflow-y: auto;
      box-shadow: 0 18px 38px rgba(0,0,0,.3);
      z-index: 5000;
      position: absolute;
      inset: auto auto auto 0;
      min-width: 100%;
    }
    .parent-option {
      padding: 8px 10px;
      border-radius: 10px;
      transition: background .15s ease, border-color .15s ease;
      border: 1px solid transparent;
    }
    .parent-option:hover {
      background: rgba(255,255,255,.05);
      border-color: rgba(255,255,255,.1);
    }
  </style>
</head>
<body class="min-vh-100">
  <div class="container py-4" style="max-width: 1100px">

    <div class="d-flex justify-content-between align-items-center mb-3">
      <div>
        <h1 class="h3 m-0">Tech Stack (%)</h1>
        <div class="text-white-50 small">Create languages and nest frameworks beneath them.</div>
      </div>
      <div class="d-flex gap-2">
        <a class="btn btn-outline-light" href="/public/admin/dashboard.php">Dashboard</a>
        <a class="btn btn-outline-light" href="/public/admin/logout.php">Logout</a>
      </div>
    </div>

    <?php if ($f): ?>
      <div class="alert alert-<?= htmlspecialchars($f['type']) ?>"><?= htmlspecialchars($f['msg']) ?></div>
    <?php endif; ?>

    <div class="card card-glass p-3 mb-3 new-skill-card">
      <div class="d-flex justify-content-between align-items-center">
        <div>
          <div class="text-white-50 small">Add New</div>
          <div class="fw-bold">Create a new bar on the homepage</div>
        </div>
        <button class="btn btn-violet" type="button" data-scroll-target="#newSkill">
          Add Skill
        </button>
      </div>

      <div class="mt-3" id="newSkill">
        <form method="post" class="row g-3">
          <input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
          <input type="hidden" name="action" value="create">

          <div class="col-md-5">
            <label class="form-label text-white-50">Label</label>
            <input class="form-control" name="label" required maxlength="120" placeholder="PHP / Laravel">
          </div>
          <div class="col-md-3">
            <label class="form-label text-white-50">Icon (RemixIcon class)</label>
            <input class="form-control" name="icon" maxlength="80" value="ri-code-s-slash-line">
          </div>
          <div class="col-md-2">
            <label class="form-label text-white-50">%</label>
            <input class="form-control" name="level" type="number" min="0" max="100" placeholder="100">
          </div>
          <div class="col-md-1">
            <label class="form-label text-white-50">Sort</label>
            <input class="form-control" name="sort_order" type="number" value="0">
          </div>
          <div class="col-md-4">
            <label class="form-label text-white-50">Category</label>
            <select class="form-select" name="category" data-parent-target="#parent-new-wrap">
              <option value="language">Language</option>
              <option value="framework">Framework</option>
            </select>
          </div>
          <div class="col-md-8">
              <div class="parent-wrap d-none" data-parent-wrap id="parent-new-wrap">
                <label class="form-label text-white-50">Parent languages (for frameworks)</label>
              <div class="dropdown w-100">
                <button class="btn parent-picker-btn w-100 d-flex justify-content-between align-items-center" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" data-bs-display="static">
                  <span class="parent-summary" data-parent-summary>Select parent languages</span>
                  <i class="ri-arrow-down-s-line ms-2"></i>
                </button>
                <div class="dropdown-menu dropdown-menu-dark w-100 p-2 parent-menu">
                  <?php foreach ($languageOptions as $lang): ?>
                    <label class="parent-option d-flex align-items-center gap-2 text-white-75 small mb-1">
                      <input class="form-check-input" type="checkbox" name="parent_id_new[]" value="<?= (int)$lang['id'] ?>" data-label="<?= htmlspecialchars((string)$lang['label']) ?>">
                      <span><?= htmlspecialchars((string)$lang['label']) ?></span>
                    </label>
                  <?php endforeach; ?>
                </div>
              </div>
              <div class="form-text text-white-50 mt-1">Choose one or more languages to nest its frameworks.</div>
            </div>
          </div>

          <div class="col-12">
            <button class="btn btn-violet">Save Skill</button>
          </div>
        </form>
      </div>
    </div>

    <div class="card card-glass p-0 overflow-hidden">
      <div class="p-3 border-bottom border-white/10 d-flex justify-content-between align-items-center">
        <div class="fw-bold">Edit Skills</div>
        <div class="text-white-50 small"><?= count($skills) ?> total</div>
      </div>

      <!-- ONE form only -->
      <form method="post">
        <input type="hidden" name="csrf" value="<?= htmlspecialchars($_SESSION['csrf']) ?>">
        <input type="hidden" name="action" value="update_many">

        <div class="table-responsive">
          <table class="table table-dark table-hover mb-0 align-middle">
            <thead>
              <tr>
                <th style="width:70px">ID</th>
                <th>Label</th>
                <th style="width:200px">Icon</th>
                <th style="width:140px">Category</th>
                <th style="width:240px">Parents</th>
                <th class="lvl">%</th>
                <th style="width:90px">Sort</th>
                <th style="width:110px">Delete</th>
              </tr>
            </thead>
            <tbody>
            <?php foreach ($skills as $s): ?>
              <tr>
                <td class="text-white-50">
                  <?= (int)$s['id'] ?>
                  <input type="hidden" name="id[]" value="<?= (int)$s['id'] ?>">
                </td>
                <td><input class="form-control" name="label[]" value="<?= htmlspecialchars((string)$s['label']) ?>" maxlength="120"></td>
                <td><input class="form-control" name="icon[]" value="<?= htmlspecialchars((string)$s['icon']) ?>" maxlength="80"></td>
                <td>
                  <?php $cat = strtolower((string)($s['category'] ?? 'language')); ?>
                  <select class="form-select" name="category[]" data-parent-target="#parent-<?= (int)$s['id'] ?>-wrap">
                    <option value="language" <?= $cat === 'language' ? 'selected' : '' ?>>Language</option>
                    <option value="framework" <?= $cat === 'framework' ? 'selected' : '' ?>>Framework</option>
                  </select>
                </td>
                <td>
                  <?php $selectedParents = $frameworkParentMap[(int)$s['id']] ?? []; ?>
                  <?php
                    $summaryText = 'Select parent languages';
                    $labels = [];
                    foreach ($selectedParents as $pid) {
                      if (isset($languageLabelMap[$pid])) $labels[] = $languageLabelMap[$pid];
                    }
                    if ($labels) $summaryText = implode(', ', $labels);
                  ?>
                  <div class="parent-wrap <?= $cat === 'framework' ? '' : 'd-none' ?>" data-parent-wrap id="parent-<?= (int)$s['id'] ?>-wrap">
                    <div class="dropdown w-100">
                      <button class="btn parent-picker-btn w-100 d-flex justify-content-between align-items-center" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" data-bs-display="static">
                        <span class="parent-summary" data-parent-summary><?= htmlspecialchars($summaryText) ?></span>
                        <i class="ri-arrow-down-s-line ms-2"></i>
                      </button>
                      <div class="dropdown-menu dropdown-menu-dark w-100 p-2 parent-menu">
                        <?php foreach ($languageOptions as $lang): ?>
                          <?php if ((int)$lang['id'] === (int)$s['id']) continue; ?>
                          <label class="parent-option d-flex align-items-center gap-2 text-white-75 small mb-1">
                            <input
                              class="form-check-input"
                              type="checkbox"
                              name="parent_id[<?= (int)$s['id'] ?>][]"
                              value="<?= (int)$lang['id'] ?>"
                              data-label="<?= htmlspecialchars((string)$lang['label']) ?>"
                              <?= in_array((int)$lang['id'], $selectedParents, true) ? 'checked' : '' ?>
                            >
                            <span><?= htmlspecialchars((string)$lang['label']) ?></span>
                          </label>
                        <?php endforeach; ?>
                      </div>
                    </div>
                  </div>
                </td>
                <td><input class="form-control" name="level[]" type="number" min="0" max="100" value="<?= (int)$s['level'] ?>"></td>
                <td><input class="form-control" name="sort_order[]" type="number" value="<?= (int)$s['sort_order'] ?>"></td>
                <td>
                  <!-- NO inner form -->
                  <button
                    class="btn btn-outline-danger btn-sm"
                    type="submit"
                    name="delete_id"
                    value="<?= (int)$s['id'] ?>"
                    data-confirm="Delete this skill?"
                  >Del</button>
                </td>
              </tr>
            <?php endforeach; ?>

            <?php if (!$skills): ?>
              <tr><td colspan="8" class="text-center text-white-50 py-4">No skills yet.</td></tr>
            <?php endif; ?>
            </tbody>
          </table>
        </div>

        <div class="p-3 border-top border-white/10">
          <button class="btn btn-violet">Save All Changes</button>
        </div>
      </form>
    </div>

  </div>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    (function ($) {
      $(function () {
        $('[data-scroll-target]').on('click', function () {
          const target = $(this).data('scroll-target');
          if (!target) return;
          const $dest = $(target);
          if ($dest.length) {
            $('html, body').animate({ scrollTop: $dest.offset().top - 20 }, 250);
          }
        });

        const syncSummary = ($wrap) => {
          const labels = $wrap
            .find('input[type="checkbox"]:checked')
            .map(function () { return $(this).data("label") || $(this).val(); })
            .get();
          $wrap.find('[data-parent-summary]').text(labels.length ? labels.join(', ') : 'Select parent languages');
        };

        const updateParentVisibility = ($select) => {
          const targetSelector = $select.data('parent-target');
          if (!targetSelector) return;
          const $wrap = $(targetSelector);
          if (!$wrap.length) return;

          const show = $select.val() === 'framework';
          $wrap.toggleClass('d-none', !show);
          if (!show) {
            $wrap.find('input[type="checkbox"]').prop('checked', false);
            $wrap.find('select').each(function () {
              $(this).find('option').prop('selected', false);
            });
          }
          syncSummary($wrap);
        };

        $('[data-parent-target]').each(function () {
          const $select = $(this);
          updateParentVisibility($select);
          $select.on('change', () => updateParentVisibility($select));
        });

        $('.parent-wrap').each(function () {
          const $wrap = $(this);
          $wrap.find('input[type="checkbox"]').on('change', () => syncSummary($wrap));
          syncSummary($wrap);
        });
      });
    })(jQuery);
  </script>
</body>
</html>
