<?php
declare(strict_types=1);

/**
 * /messages/index.php
 * Приватні повідомлення — список діалогів:
 * - показує всі розмови, де ти учасник
 * - аватар співрозмовника + ПІБ під аватаром
 * - поряд останнє повідомлення + час
 * - нові повідомлення піднімаються вверх і підсвічуються зеленим
 * - переходи в діалог
 *
 * ВАЖЛИВО:
 * - більше НЕ показує порожні треди без жодного повідомлення
 */

require_once __DIR__ . '/../includes/start.php';

$pdo = db();
$me  = current_user();
$u   = $me;

require_login();

/* ===== helpers ===== */
if (!function_exists('h')) {
    function h(?string $s): string { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
}

/* ===== lang detect (uk/ru/en) ===== */
$lang = 'uk';
if (isset($_SESSION['lang'])) {
    $lang = (string)$_SESSION['lang'];
} elseif (is_array($me) && isset($me['lang'])) {
    $lang = (string)$me['lang'];
}
$lang = strtolower(trim($lang));
if (!in_array($lang, ['uk','ru','en'], true)) $lang = 'uk';

function msg_t(string $key, string $lang): string {
    static $dict = [
        'uk' => [
            'title' => 'Повідомлення',
            'back'  => 'На головну',
            'empty' => 'Поки що немає жодної розмови.',
            'hint'  => 'Коли хтось напише тобі або ти напишеш комусь — діалог зʼявиться тут.',
            'closed'=> 'Розмова завершена',
            'new'   => 'Нове',
            'attach'=> 'Вкладення',
            'open'  => 'Відкрити',
        ],
        'ru' => [
            'title' => 'Сообщения',
            'back'  => 'На главную',
            'empty' => 'Пока что нет ни одного диалога.',
            'hint'  => 'Когда кто-то напишет тебе или ты напишешь кому-то — диалог появится здесь.',
            'closed'=> 'Диалог завершён',
            'new'   => 'Новое',
            'attach'=> 'Вложение',
            'open'  => 'Открыть',
        ],
        'en' => [
            'title' => 'Messages',
            'back'  => 'Go to feed',
            'empty' => 'No conversations yet.',
            'hint'  => 'When someone messages you or you message someone — the dialog will appear here.',
            'closed'=> 'Conversation closed',
            'new'   => 'New',
            'attach'=> 'Attachment',
            'open'  => 'Open',
        ],
    ];
    return $dict[$lang][$key] ?? ($dict['uk'][$key] ?? $key);
}

function msg_ensure_schema(PDO $pdo): void {
    $pdo->exec("
CREATE TABLE IF NOT EXISTS `message_threads` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user1_id` INT(10) UNSIGNED NOT NULL,
  `user2_id` INT(10) UNSIGNED NOT NULL,
  `created_at` DATETIME NOT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  `last_message_at` DATETIME DEFAULT NULL,
  `last_message_id` BIGINT(20) UNSIGNED DEFAULT NULL,
  `is_closed` TINYINT(1) NOT NULL DEFAULT 0,
  `closed_by_user_id` INT(10) UNSIGNED DEFAULT NULL,
  `closed_at` DATETIME DEFAULT NULL,
  `user1_last_read_at` DATETIME DEFAULT NULL,
  `user2_last_read_at` DATETIME DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_pair` (`user1_id`,`user2_id`),
  KEY `idx_user1` (`user1_id`),
  KEY `idx_user2` (`user2_id`),
  KEY `idx_last_message_at` (`last_message_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
");

    $pdo->exec("
CREATE TABLE IF NOT EXISTS `message_messages` (
  `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `thread_id` INT(10) UNSIGNED NOT NULL,
  `sender_id` INT(10) UNSIGNED NOT NULL,
  `msg_type` ENUM('user','system') NOT NULL DEFAULT 'user',
  `body` TEXT COLLATE utf8mb4_unicode_ci,
  `has_attachments` TINYINT(1) NOT NULL DEFAULT 0,
  `created_at` DATETIME NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_thread_id` (`thread_id`,`id`),
  KEY `idx_sender_id` (`sender_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
");

    $pdo->exec("
CREATE TABLE IF NOT EXISTS `message_attachments` (
  `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `message_id` BIGINT(20) UNSIGNED NOT NULL,
  `rel_path` VARCHAR(512) COLLATE utf8mb4_unicode_ci NOT NULL,
  `stored_name` VARCHAR(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `original_name` VARCHAR(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `mime` VARCHAR(190) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `size_bytes` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
  `created_at` DATETIME NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_message_id` (`message_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
");
}

function msg_initials(string $name): string {
    $name = trim($name);
    if ($name === '') return '?';
    $parts = preg_split('/\s+/u', $name) ?: [];
    $a = mb_substr($parts[0] ?? $name, 0, 1, 'UTF-8');
    $b = mb_substr($parts[1] ?? '', 0, 1, 'UTF-8');
    $res = mb_strtoupper($a . $b, 'UTF-8');
    return $res !== '' ? $res : '?';
}

function msg_avatar_src(array $user): string {
    $p = trim((string)($user['avatar_path'] ?? ''));
    if ($p !== '') return $p;

    $name = (string)($user['full_name'] ?? ($user['username'] ?? 'U'));
    $ini  = msg_initials($name);
    $id   = (int)($user['id'] ?? 0);
    $hue  = ($id * 47) % 360;
    $svg  = '<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96">'
          . '<defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1">'
          . '<stop offset="0" stop-color="hsl('.$hue.',85%,55%)"/>'
          . '<stop offset="1" stop-color="hsl('.(($hue+40)%360).',85%,50%)"/>'
          . '</linearGradient></defs>'
          . '<rect width="96" height="96" rx="20" fill="url(#g)"/>'
          . '<text x="50%" y="56%" dominant-baseline="middle" text-anchor="middle" '
          . 'font-family="Arial, sans-serif" font-size="34" fill="white" font-weight="700">'.$ini.'</text>'
          . '</svg>';
    return 'data:image/svg+xml;utf8,' . rawurlencode($svg);
}

function msg_preview(string $body, int $hasAtt, string $lang): string {
    $body = trim($body);
    if ($body !== '') return $body;
    if ($hasAtt) return msg_t('attach', $lang);
    return '';
}

try {
    msg_ensure_schema($pdo);
} catch (Throwable $e) {
    $title = msg_t('title', $lang);
    $seo_noindex = true;
    require __DIR__ . '/../includes/header.php';
    echo '<div class="container my-4"><div class="alert alert-danger">DB schema error: ' . h($e->getMessage()) . '</div></div>';
    require __DIR__ . '/../includes/footer.php';
    exit;
}

/* quick jump: /messages/?u=username */
$jumpUser = trim((string)($_GET['u'] ?? ''));
if ($jumpUser !== '') {
    header('Location: /messages/dialog.php?u=' . urlencode($jumpUser));
    exit;
}

$meId = (int)$me['id'];

$title = msg_t('title', $lang);
$seo_noindex = true;

require __DIR__ . '/../includes/header.php';
?>

<link rel="stylesheet" href="/css/messages.css?v=3">

<div class="feed-layout">
  <aside>
    <div class="sidebar-sticky">
      <?php require __DIR__ . '/../blocks/profile.php'; ?>
    </div>
  </aside>

  <section>
    <div class="container my-4">

      <div class="d-flex align-items-center justify-content-between flex-wrap gap-2 mb-3">
        <h1 class="h4 mb-0"><?= h(msg_t('title', $lang)) ?></h1>
        <a class="btn btn-sm btn-outline-secondary" href="/"><?= h(msg_t('back', $lang)) ?></a>
      </div>

      <?php
      $sql = "
        SELECT
          t.*,
          lm.sender_id AS last_sender_id,
          lm.msg_type   AS last_msg_type,
          lm.body       AS last_body,
          lm.has_attachments AS last_has_attachments,

          CASE WHEN t.user1_id = :me1 THEN u2.id ELSE u1.id END AS peer_id,
          CASE WHEN t.user1_id = :me2 THEN u2.username ELSE u1.username END AS peer_username,
          CASE WHEN t.user1_id = :me3 THEN u2.full_name ELSE u1.full_name END AS peer_full_name,
          CASE WHEN t.user1_id = :me4 THEN u2.avatar_path ELSE u1.avatar_path END AS peer_avatar_path,

          CASE
            WHEN t.user1_id = :me5 THEN
              (t.last_message_at IS NOT NULL
                AND (t.user1_last_read_at IS NULL OR t.last_message_at > t.user1_last_read_at)
                AND (lm.sender_id IS NULL OR lm.sender_id <> :me6))
            ELSE
              (t.last_message_at IS NOT NULL
                AND (t.user2_last_read_at IS NULL OR t.last_message_at > t.user2_last_read_at)
                AND (lm.sender_id IS NULL OR lm.sender_id <> :me7))
          END AS is_unread

        FROM message_threads t
        JOIN users u1 ON u1.id = t.user1_id
        JOIN users u2 ON u2.id = t.user2_id
        LEFT JOIN message_messages lm ON lm.id = t.last_message_id
        WHERE
          (t.user1_id = :me8 OR t.user2_id = :me9)
          AND t.last_message_id IS NOT NULL
        ORDER BY IFNULL(t.last_message_at, t.created_at) DESC, t.id DESC
        LIMIT 100
      ";

      $st = $pdo->prepare($sql);
      $st->execute([
        ':me1' => $meId,
        ':me2' => $meId,
        ':me3' => $meId,
        ':me4' => $meId,
        ':me5' => $meId,
        ':me6' => $meId,
        ':me7' => $meId,
        ':me8' => $meId,
        ':me9' => $meId,
      ]);

      $threads = $st->fetchAll(PDO::FETCH_ASSOC);
      ?>

      <?php if (!$threads): ?>
        <div class="msg-empty card border-0 shadow-sm">
          <div class="card-body">
            <div class="msg-empty-title"><?= h(msg_t('empty', $lang)) ?></div>
            <div class="text-muted"><?= h(msg_t('hint', $lang)) ?></div>
          </div>
        </div>
      <?php else: ?>
        <div class="msg-threads">
          <?php foreach ($threads as $trow): ?>
            <?php
              $peer = [
                'id' => (int)$trow['peer_id'],
                'username' => (string)$trow['peer_username'],
                'full_name' => (string)$trow['peer_full_name'],
                'avatar_path' => (string)($trow['peer_avatar_path'] ?? ''),
              ];
              $avatar = msg_avatar_src($peer);
              $lastText = msg_preview((string)($trow['last_body'] ?? ''), (int)($trow['last_has_attachments'] ?? 0), $lang);
              if ($lastText === '') $lastText = '…';
              $isUnread = (int)($trow['is_unread'] ?? 0) === 1;
              $isClosed = (int)($trow['is_closed'] ?? 0) === 1;
              $time = (string)($trow['last_message_at'] ?? '');
              $timeOut = $time ? date('d.m.Y H:i', strtotime($time)) : '';
            ?>
            <a class="msg-thread <?= $isUnread ? 'unread' : '' ?>" href="/messages/dialog.php?t=<?= (int)$trow['id'] ?>">
              <div class="msg-thread-left">
                <div class="msg-thread-ava">
                  <img src="<?= h($avatar) ?>" alt="">
                </div>
                <div class="msg-thread-name" title="<?= h($peer['full_name']) ?>">
                  <?= h($peer['full_name']) ?>
                </div>
              </div>

              <div class="msg-thread-mid">
                <div class="msg-thread-last" title="<?= h($lastText) ?>">
                  <?= h($lastText) ?>
                </div>
                <div class="msg-thread-meta">
                  <?php if ($isUnread): ?>
                    <span class="badge bg-success-subtle text-success-emphasis border border-success-subtle"><?= h(msg_t('new', $lang)) ?></span>
                  <?php endif; ?>
                  <?php if ($isClosed): ?>
                    <span class="badge bg-secondary-subtle text-secondary-emphasis border border-secondary-subtle"><?= h(msg_t('closed', $lang)) ?></span>
                  <?php endif; ?>
                </div>
              </div>

              <div class="msg-thread-right">
                <?php if ($timeOut): ?>
                  <div class="msg-thread-time"><?= h($timeOut) ?></div>
                <?php endif; ?>
                <div class="msg-thread-open"><?= h(msg_t('open', $lang)) ?> →</div>
              </div>
            </a>
          <?php endforeach; ?>
        </div>
      <?php endif; ?>

    </div>
  </section>

  <aside>
    <div class="sidebar-sticky">
      <?php require __DIR__ . '/../blocks/groups.php'; ?>
    </div>
  </aside>
</div>

<?php require __DIR__ . '/../includes/footer.php'; ?>