/**
 * Matrix Cycling Blog - Data Store & Post Scheduler
 * Tailored for MatrixHasYou // Ulyanovsk (Volga), Aspect Air 2025 29" MTB, Books, Gym, Tennis, Journal.
 */

window.MatrixStore = (function () {
    const STORAGE_KEY_POSTS = "matrix_cycling_posts_v6";
    const STORAGE_KEY_PHOTOS = "matrix_cycling_photos_v6";

    const DEFAULT_NOTES = [
        {
            "id": "note-aspect-specs-001",
            "type": "note",
            "category": "howto",
            "title": "🚴‍♂️ ТТХ моего велосипеда: Aspect Air 29\" (2025) — Полный мануал, стандарты и расходники",
            "date": "2026-08-24T00:30:00.000Z",
            "publishAt": "2026-08-24T00:30:00.000Z",
            "status": "published",
            "heroImage": "images/aspect_matrix_bridge.jpg",
            "tags": [
                "aspect_air_2025",
                "29er",
                "mtb_specs",
                "shimano_cues",
                "ulyanovsk",
                "matrix"
            ],
            "telemetry": {
                "distance": "1x9 Shimano CUES",
                "avgSpeed": "Sunshine 11-46T 9S",
                "elevation": "Prowheel 34T (24mm)",
                "watts": "EXSHO Air 100mm (34mm)"
            },
            "content": `Полная техническая спецификация, стандарты узлов, размеры расходников и геометрия найнера **Aspect Air 29" (2025)**. Этот мануал служит эталонным справочником по всем компонентам для обслуживания, ТО и быстрого подбора запчастей при ремонте.

---

### 1. ⚙️ Трансмиссия и Привод (Drivetrain)
* **Конфигурация:** \`1x9\` скоростей
* **Задний переключатель:** \`Shimano CUES RD-U4000\` (с технологией Shadow RD, прямая подводка троса)
* **Манетка переключения:** \`Shimano CUES SL-U4000\` (технология 2-Way Release)
* **Система шатунов:** \`PROWHEEL C10Y-NW 34T\` с полым валом **Ø24 мм** (Hollowtech II совместимый стандарт)
  * Длина шатунов: **175 мм** (для рам M / L / XL) / **170 мм** (для рамы S)
  * Звезда: **34 зуба (34T)**, профиль **Narrow-Wide** (защита от спадания цепи)
* **Каретка:** Резьбовая \`BSA 68/73 мм\` (B902 / внешние промышленные подшипники под вал 24 мм)
* **Кассета:** \`Sunshine MTB-CS-HR9-46 9S\` (диапазон **11-46T**: звезды 11-13-16-20-24-28-34-40-46)
* **Барабан втулки:** Стандарт \`Shimano HG (HyperGlide)\`
* **Цепь:** \`KMC XGLIDE\` (9 скоростей, замок быстросъемный)

---

### 2. 🛞 Колеса, Обода и Покрышки (Wheelset)
* **Размер колес:** \`29 дюймов (622 мм)\`
* **Обода:** \`Code D23race\` — двойные алюминиевые, **Tubeless Ready** (готовы под бескамерную установку), ETRTO \`622 x 23 мм\`, 32 спицы (32H), ниппель **Presta (FV)**
* **Передняя втулка:** \`Code H1.2\` (алюминиевый корпус на 2 промышленных подшипниках, стандарт **Boost 15x110 мм** на сквозной оси)
* **Задняя втулка:** \`Code H1.2\` (алюминиевый корпус на 4 промышленных подшипниках, стандарт **Boost 12x148 мм** на сквозной оси, барабан HG)
* **Покрышки:** \`Kenda Booster K1227 Skinwall 29x2.25"\` (универсальный накатистый XC-протектор со светлым бортом)
* **Рабочее давление шин:**
  * Грунт / Корни / Песок: **1.8–1.9 бар (26–28 PSI)**
  * Асфальт / Твердое покрытие: **2.0–2.2 бар (29–32 PSI)**

---

### 3. 🔱 Амортизационная вилка (Suspension Fork)
* **Модель:** \`EXSHO FIX 15 AIR / HLO / REB\`
* **Тип:** Воздушно-масляная (Air Spring)
* **Ход вилки:** **100 мм**
* **Ось:** Сквозная **Boost 15x110 мм**
* **Ноги:** Анодированный алюминиевый сплав, диаметр **Ø34 мм** (повышенная торсионная жесткость)
* **Бушинги:** Металло-тефлоновые скользящие направляющие
* **Регулировки:**
  1. *Воздушная камера (Air Preload)* — накачка насосом высокого давления под вес райдера
  2. *Блокировка (HLO - Hydraulic Lockout)* — флажок на короне вилки
  3. *Регулировка отскока (Rebound)* — крутилка в нижней части правой ноги

---

### 4. 🛑 Тормозная система (Braking System)
* **Тормоза:** \`Shimano MT200\` — двухпоршневая гидравлика на минеральном масле Shimano Mineral Oil
* **Крепление заднего калипера:** \`Post Mount (PM)\` внутри заднего треугольника на нижнем пере (защита от ударов)
* **Передний ротор:** \`RPT-009 Ø180 мм\` (6 болтов)
* **Задний ротор:** \`RPT-009 Ø160 мм\` (6 болтов)
* **Тормозные колодки:** \`B01S / B03S / B05S Resin (органические)\`

---

### 5. 📐 Рама, Рулевое управление и Кокпит (Frame & Cockpit)
* **Материал рамы:** \`Alloy 6061\` (гидроформированные трубы переменного сечения, двойной баттинг, полированные швы *Smooth Welding*)
* **Стандарты рамы:** Дропауты под сквозную ось **Boost 12x148 мм**, скрытая внутренняя проводка тросов и гидролиний (*IHR / Silent Cables*)
* **Рулевая колонка:** \`Gineyea T05 52-52/39.8\` (полуинтегрированная на закрытых промподшипниках под конусный шток 1.5"-1.5")
* **Руль:** \`Code-802 Alloy\` — диаметр под вынос **Ø31.8 мм**, ширина **760 мм**, подъем 15 мм, загиб назад 6°
* **Вынос руля:** \`Code AS-002N Alloy\` (угол 0°, длина 60 мм под рамы M/L, 50 мм под S, 70 мм под XL)
* **Грипсы:** \`Code G104\` (эргономичный цепкий компаунд с алюминиевым замком Lock-on)
* **Подседельный штырь:** \`Code-609 Alloy\`, диаметр **Ø31.6 мм**, длина **400 мм**, надежный двухболтовый замок
* **Седло:** \`Code-12231\` (размеры **245 x 155 мм**, анатомический вырез и плотная спортивная пена)
* **Вес велосипеда:** ~**13.4 кг** (в сборе)

> [!TIP] Заметка для ТО и быстрого заказа расходников:
> * **Кассета:** 9 скоростей, барабан HG, диапазон 11-46T.
> * **Цепь:** 9-speed KMC / Shimano (116 звеньев).
> * **Колодки:** Shimano B05S Resin.
> * **Ниппель:** Presta (FV 48 мм).
> * **Оси:** Перед 15x110 Boost, Зад 12x148 Boost.`
        }
    ];

    const DEFAULT_PHOTOS = [];

    // --- Local Storage Management ---

    function getStoredNotes() {
        try {
            const raw = localStorage.getItem(STORAGE_KEY_POSTS);
            if (raw === null) {
                localStorage.setItem(STORAGE_KEY_POSTS, JSON.stringify(DEFAULT_NOTES));
                return DEFAULT_NOTES;
            }
            return JSON.parse(raw);
        } catch (e) {
            console.error("Error reading notes from localStorage", e);
            return DEFAULT_NOTES;
        }
    }

    function saveStoredNotes(notes) {
        try {
            localStorage.setItem(STORAGE_KEY_POSTS, JSON.stringify(notes));
        } catch (e) {
            console.error("Error saving notes to localStorage", e);
        }
    }

    function getStoredPhotos() {
        try {
            const raw = localStorage.getItem(STORAGE_KEY_PHOTOS);
            if (raw === null) {
                localStorage.setItem(STORAGE_KEY_PHOTOS, JSON.stringify(DEFAULT_PHOTOS));
                return DEFAULT_PHOTOS;
            }
            return JSON.parse(raw);
        } catch (e) {
            console.error("Error reading photos from localStorage", e);
            return DEFAULT_PHOTOS;
        }
    }

    function saveStoredPhotos(photos) {
        try {
            localStorage.setItem(STORAGE_KEY_PHOTOS, JSON.stringify(photos));
        } catch (e) {
            console.error("Error saving photos to localStorage", e);
        }
    }

    // --- Public Queries ---

    function isItemLive(item) {
        if (!item || item.status === "draft") return false;
        const pubDate = new Date(item.publishAt || item.date);
        return pubDate <= new Date();
    }

    function getPublishedNotes(category = null) {
        const now = new Date();
        let notes = getStoredNotes().filter(note => {
            if (note.status === "draft") return false;
            const pubDate = new Date(note.publishAt || note.date);
            return pubDate <= now;
        });

        if (category && category !== "all") {
            notes = notes.filter(n => n.category === category);
        }

        return notes.sort((a, b) => new Date(b.publishAt || b.date) - new Date(a.publishAt || a.date));
    }

    function getAllNotes() {
        return getStoredNotes().sort((a, b) => new Date(b.date || b.publishAt) - new Date(a.date || a.publishAt));
    }

    function getPublishedPhotos() {
        const now = new Date();
        return getStoredPhotos().filter(photo => {
            if (photo.status === "draft") return false;
            const pubDate = new Date(photo.publishAt || photo.date);
            return pubDate <= now;
        }).sort((a, b) => new Date(b.publishAt || b.date) - new Date(a.publishAt || a.date));
    }

    function getAllPhotos() {
        return getStoredPhotos().sort((a, b) => new Date(b.date || b.publishAt) - new Date(a.date || a.publishAt));
    }

    // --- Mutations ---

    function saveNote(noteData) {
        const notes = getStoredNotes();
        const nowIso = new Date().toISOString();

        if (noteData.id) {
            const index = notes.findIndex(n => n.id === noteData.id);
            if (index !== -1) {
                notes[index] = { ...notes[index], ...noteData, updatedAt: nowIso };
            } else {
                notes.unshift({ ...noteData, createdAt: nowIso, updatedAt: nowIso });
            }
        } else {
            const newId = "note-" + Date.now();
            notes.unshift({
                id: newId,
                ...noteData,
                createdAt: nowIso,
                updatedAt: nowIso
            });
        }

        saveStoredNotes(notes);
        return true;
    }

    function deleteNote(id) {
        let notes = getStoredNotes();
        notes = notes.filter(n => n.id !== id);
        saveStoredNotes(notes);
        return true;
    }

    function savePhoto(photoData) {
        const photos = getStoredPhotos();
        const nowIso = new Date().toISOString();

        if (photoData.id) {
            const index = photos.findIndex(p => p.id === photoData.id);
            if (index !== -1) {
                photos[index] = { ...photos[index], ...photoData, updatedAt: nowIso };
            } else {
                photos.unshift({ ...photoData, createdAt: nowIso, updatedAt: nowIso });
            }
        } else {
            const newId = "photo-" + Date.now();
            photos.unshift({
                id: newId,
                ...photoData,
                createdAt: nowIso,
                updatedAt: nowIso
            });
        }

        saveStoredPhotos(photos);
        return true;
    }

    function deletePhoto(id) {
        let photos = getStoredPhotos();
        photos = photos.filter(p => p.id !== id);
        saveStoredPhotos(photos);
        return true;
    }

    function exportDatabase() {
        return JSON.stringify({
            version: "6.0",
            exportedAt: new Date().toISOString(),
            notes: getStoredNotes(),
            photos: getStoredPhotos()
        }, null, 2);
    }

    function importDatabase(jsonString) {
        try {
            const data = JSON.parse(jsonString);
            if (Array.isArray(data.notes)) saveStoredNotes(data.notes);
            if (Array.isArray(data.photos)) saveStoredPhotos(data.photos);
            return true;
        } catch (e) {
            console.error("Import failed", e);
            return false;
        }
    }

    return {
        isItemLive,
        getLiveNotes: getPublishedNotes,
        getPublishedNotes,
        getAllNotes,
        getAllNotesForAdmin: getAllNotes,
        getLivePhotos: getPublishedPhotos,
        getPublishedPhotos,
        getAllPhotos,
        getAllPhotosForAdmin: getAllPhotos,
        saveNote,
        deleteNote,
        savePhoto,
        deletePhoto,
        exportDatabase,
        importDatabase
    };
})();
