#!/usr/bin/env python3

import os
import sys
import re
import argparse
import requests
import json
from datetime import datetime
import random

def get_first_todo_article(progress_file, blog_dir):
    """Pobiera pierwszy nieukończony artykuł z pliku progress.md.
    Jeśli nie ma nieukończonych artykułów, dodaje nowe na podstawie istniejących katalogów."""
    with open(progress_file, 'r') as f:
        content = f.read()
    
    pattern = r'- \[ \] (\d+\.[^\n]+)'  # Nieukończone artykuły
    matches = re.findall(pattern, content)
    
    if matches:
        return matches[0]
    else:
        print("Nie znaleziono żadnych nieukończonych artykułów w pliku progress.md")
        print("Dodaję nowe artykuły na podstawie istniejących katalogów...")
        
        # Lista wszystkich katalogów w blog_dir
        subdirs = [d for d in os.listdir(blog_dir) if os.path.isdir(os.path.join(blog_dir, d))]
        
        # Sortowanie katalogów numerycznie
        def extract_number(dirname):
            try:
                return int(dirname.split('.')[0])
            except (ValueError, IndexError):
                return 999999  # Dla katalogów bez numeru
        
        subdirs.sort(key=extract_number)
        
        if not subdirs:
            print("Nie znaleziono żadnych katalogów artykułów!")
            sys.exit(1)
            
        # Znajdź najwyższy numer artykułu
        last_num = extract_number(subdirs[-1])
        
        # Dodaj 10 nowych artykułów do progress.md
        with open(progress_file, 'a') as f:
            f.write("\n# Nowe artykuły dodane automatycznie\n\n")
            for i in range(1, 11):  # Dodaj 10 nowych artykułów
                new_num = last_num + i
                new_article = f"{new_num}.nowy-artykul-{i}"
                f.write(f"- [ ] {new_article}\n")
        
        print(f"Dodano 10 nowych artykułów do pliku progress.md")
        
        # Po dodaniu, ponownie spróbuj znaleźć pierwszy nieukończony artykuł
        with open(progress_file, 'r') as f:
            content = f.read()
        
        matches = re.findall(pattern, content)
        if matches:
            return matches[0]
        else:
            print("Nie udało się dodać nowych artykułów do pliku progress.md")
            sys.exit(1)

def get_article_title(article_input, progress_file):
    """Pobiera tytuł artykułu na podstawie numeru lub pełnej nazwy z pliku progress.md."""
    with open(progress_file, 'r') as f:
        content = f.read()
    
    # Sprawdź, czy podano pełny tytuł artykułu czy tylko numer
    if '.' in article_input:
        # Podano pełny tytuł, sprawdź czy istnieje w pliku
        
        # Najpierw sprawdź, czy artykuł nie został już oznaczony jako ukończony
        pattern_completed = r"- \[x\] " + re.escape(article_input)
        if re.search(pattern_completed, content):
            print(f"Artykuł '{article_input}' jest już oznaczony jako ukończony w pliku progress.md")
            # Zwracamy tytuł mimo to, aby można było nadpisać artykuł
            return article_input
        
        # Sprawdź czy artykuł jest do zrobienia
        pattern = r"- \[ \] " + re.escape(article_input)
        if re.search(pattern, content):
            return article_input
        else:
            # Wypisz kilka linii pliku progress.md dla debugowania
            print(f"Nie znaleziono artykułu '{article_input}' w pliku progress.md")
            print("Kilka linii z pliku progress.md:")
            lines = content.split('\n')
            # Wypisz pierwsze 10 linii
            for i in range(min(10, len(lines))):
                print(lines[i])
            print("...")
            sys.exit(1)
    else:
        # Podano tylko numer, szukamy artykułu z tym numerem
        pattern = r'- \[ \] (\d+\.[^\ \n]+)'
        matches = re.findall(pattern, content)
        
        for match in matches:
            if match.startswith(str(article_input) + '.'):
                return match
        
        print(f"Nie znaleziono artykułu o numerze {article_input} w pliku progress.md")
        sys.exit(1)

def create_article_directory(blog_dir, article_title):
    """Tworzy katalog dla artykułu."""
    article_dir = os.path.join(blog_dir, article_title)
    os.makedirs(article_dir, exist_ok=True)
    return article_dir

def generate_article_content(article_title, model_name="llama3"):
    """Generuje treść artykułu używając Ollamy zamiast OpenAI."""
    readable_title = article_title.split('.', 1)[1].replace('-', ' ').title()

    # Prompt oparty o wytyczne z README.md
    prompt = f"""nothinking Napisz bardzo rozbudowany i profesjonalny artykuł na blog firmy hostingowej IQHost o tytule: "{readable_title}".

Artykuł powinien:
- Mieć długość minimum 4000 słów (jeśli temat na to pozwala, więcej).
- Wyjaśniać każdy aspekt tematu w sposób wyczerpujący.
- W każdej sekcji:
  - Podaj definicje, kontekst i przykłady.
  - Wymień zalety i wady różnych podejść.
  - Zawieraj porady eksperckie i najlepsze praktyki.
  - Ostrzeż przed typowymi błędami.
- Uwzględnij także pytania najczęściej zadawane przez użytkowników (FAQ).
- Używaj rozbudowanych sekcji i podsekcji.

1. Główny tytuł: "# 🏆 {readable_title}"
2. Lead/Intro: Krótki, angażujący wstęp (2-3 zdania) jako cytat
3. Ekspresowe podsumowanie (opcjonalne): 3-4 kluczowe punkty
4. Sekcja "Spis Treści" (placeholder)
5. Główne sekcje tematyczne z nagłówkami rozpoczynającymi się od emoji
6. Podsumowanie na końcu z call to action

Formatowanie:
- Używaj emoji na początku każdego głównego nagłówka
- Formatuj ważne pojęcia używając **pogrubienia**
- Używaj *kursywy* dla akcentów i cytatów
- Używaj `kod` dla terminów technicznych, komend, itp.
- Dodaj bloki cytatów dla ważnych uwag lub wskazówek
- Używaj list wypunktowanych i numerowanych dla czytelności

Artykuł powinien być profesjonalny, ale przyjazny w tonie, z wartościową zawartością merytoryczną odpowiadającą na potrzeby czytelników zainteresowanych hostingiem, domenami, serwerami i technologiami internetowymi.

Napisz pełny artykuł w formacie Markdown, bez sekcji front matter YAML (zostanie dodana oddzielnie).

PAMIĘTAJ: Artykuł musi być szczegółowy, kompleksowy i mieć MINIMUM 4000 słów długości. Każda sekcja musi być rozbudowana, z wieloma przykładami i szczegółowymi wyjaśnieniami.
"""

    system_message = 'Jesteś doświadczonym ekspertem w dziedzinie hostingu, domen i technologii serwerowych. Twoim celem jest napisanie pełnowartościowych artykułów blogowych, które nie tylko odpowiadają na podstawowe pytania, ale również dostarczają dogłębnej analizy, przykładów, porównań oraz praktycznych porad dla profesjonalistów i zaawansowanych użytkowników.'

    # Definiowanie danych dla API Ollama
    data = {
        "model": model_name,
        "prompt": prompt,
        "system": system_message,
        "stream": False,
        "options": {
#            "temperature": 0.6,  # Lekko zwiększona losowość dla kreatywności
#            "top_p": 0.95,  # Zmniejszenie z domyślnej 1.0 dla bardziej spójnych wyników
#            "top_k": 20,  # Standardowa wartość dla zbalansowanej generacji
            "num_predict": 30000,  # Zwiększenie limitu generowanych tokenów
            "repeat_penalty": 1.1  # Delikatna kara za powtórzenia dla lepszej różnorodności
        }
    }

    print(f"Generowanie treści artykułu używając Ollama API z modelem {model_name}...")
    try:
        # Ollama domyślnie nasłuchuje na localhost:11434
        response = requests.post('http://mietek:11434/api/generate', json=data)
        
        if response.status_code == 200:
            content = response.json().get('response', '')
            # Usuń ewentualne otaczające bloki kodu
            content = re.sub(r'^```markdown\s*', '', content)
            content = re.sub(r'\s*```$', '', content)
            content = re.sub(r'<think>.*?</think>', '', content, flags=re.DOTALL)
            return content.strip()
        else:
            print(f"Błąd API Ollama przy generowaniu treści: {response.status_code} - {response.text}")
            return None
    except Exception as e:
        print(f"Wystąpił błąd podczas komunikacji z Ollama: {str(e)}")
        return None

def create_yaml_metadata(article_title):
    """Tworzy sekcję metadanych YAML zgodnie z wytycznymi z README.md."""
    readable_title = article_title.split('.', 1)[1].replace('-', ' ').title()
    slug = article_title.split('.', 1)[1]
    current_date = datetime.now().strftime('%Y-%m-%d %H:%M')

    # Generowanie tagów z tytułu
    keywords = [kw.strip() for kw in readable_title.lower().split() if len(kw) > 3]
    tags = [tag.capitalize() for tag in keywords[:3]]

    # Kategorie
    categories = ["Hosting"]
    keywords_lower = readable_title.lower()
    
    if "wordpress" in keywords_lower:
        categories.append("WordPress")
    if any(word in keywords_lower for word in ["błąd", "blad", "problem"]):
        categories.append("Błędy Serwera")
    if any(word in keywords_lower for word in ["bezpieczeństwo", "bezpieczenstwo", "zabezpiecz"]):
        categories.append("Bezpieczeństwo")
    if "serwer" in keywords_lower:
        categories.append("Serwery")
    if any(word in keywords_lower for word in ["email", "poczta", "mail"]):
        categories.append("Email")

    # Opis
    description = f"Dowiedz się wszystkiego o: {readable_title}. Praktyczny przewodnik od IQHost."

    yaml = f"""---
title: {readable_title}
slug: {slug}
description: "{description[:160]}"
keywords: [{', '.join(keywords)}]
tags: [{', '.join(tags)}]
author: Zespół IQHost
date: {current_date}
process: 
  markdown: true
taxonomy:
  category:
{chr(10).join(['    - ' + category for category in categories])}
classes:
  quick-start: true
  info: true
  tip: true
  warning: true
  checklist: true
  cta-banner: true
---

"""
    return yaml

def save_article(article_dir, article_title, article_content):
    """Zapisuje artykuł do pliku post.md."""
    yaml_metadata = create_yaml_metadata(article_title)
    full_content = yaml_metadata + article_content
    
    with open(os.path.join(article_dir, 'post.md'), 'w') as f:
        f.write(full_content)

def create_empty_image_placeholder(article_dir):
    """Tworzy pusty plik placeholder dla obrazu."""
    with open(os.path.join(article_dir, 'main.png.txt'), 'w') as f:
        f.write("To jest placeholder dla obrazu głównego artykułu.")

def update_progress_file(progress_file, article_title):
    """Aktualizuje plik progress.md, zmieniając status artykułu na ukończony."""
    with open(progress_file, 'r') as f:
        content = f.read()
    
    # Zmień status artykułu z [ ] na [x]
    updated_content = content.replace(f'- [ ] {article_title}', f'- [x] {article_title}')
    
    with open(progress_file, 'w') as f:
        f.write(updated_content)

def create_progress_file(blog_dir):
    """Tworzy plik progress.md na podstawie istniejących katalogów jeśli nie istnieje."""
    progress_file = os.path.join(blog_dir, 'progress.md')
    
    # Sprawdź czy plik progress.md istnieje
    if os.path.exists(progress_file):
        print(f"Plik {progress_file} już istnieje. Używam istniejącego pliku.")
        return progress_file
        
    print(f"Tworzę nowy plik {progress_file} na podstawie istniejących katalogów...")
    
    # Lista wszystkich katalogów w blog_dir
    subdirs = [d for d in os.listdir(blog_dir) if os.path.isdir(os.path.join(blog_dir, d))]
    
    # Sortowanie katalogów numerycznie
    def extract_number(dirname):
        try:
            return int(dirname.split('.')[0])
        except (ValueError, IndexError):
            return 999999  # Dla katalogów bez numeru
    
    subdirs.sort(key=extract_number)
    
    # Tworzenie zawartości pliku progress.md
    content = "# Postęp pisania artykułów\n\n"
    
    # Dodawanie istniejących katalogów jako ukończone artykuły
    for subdir in subdirs:
        content += f"- [x] {subdir}\n"
    
    # Opcjonalnie, dodaj pewną liczbę placeholderów dla przyszłych artykułów
    if subdirs:
        last_num = extract_number(subdirs[-1])
        for i in range(1, 11):  # Dodaj 10 nowych artykułów
            new_num = last_num + i
            content += f"- [ ] {new_num}.nowy-artykul-{i}\n"
    
    # Zapisz plik
    with open(progress_file, 'w') as f:
        f.write(content)
    
    print(f"Utworzono plik {progress_file} z {len(subdirs)} ukończonymi artykułami.")
    return progress_file

def generate_sample_content(article_title):
    """Generuje przykładową treść artykułu bez korzystania z API."""
    readable_title = article_title.split('.', 1)[1].replace('-', ' ').title()
    
    content = f"""
# 🏆 {readable_title}

> **Lead/Intro:** Witaj w kompleksowym przewodniku na temat {readable_title.lower()}. W tym artykule przedstawimy najważniejsze informacje, praktyczne wskazówki oraz rozwiązania, które pomogą Ci skutecznie zarządzać tym aspektem Twojej obecności online.

### ⚡ Ekspresowe Podsumowanie:

1. **Kluczowy punkt 1:** {readable_title} stanowi istotny element infrastruktury internetowej.
2. **Kluczowy punkt 2:** Odpowiednia konfiguracja zwiększa wydajność i bezpieczeństwo.
3. **Kluczowy punkt 3:** Regularne aktualizacje zapewniają stabilność działania.

---

## 🗺️ Spis Treści - Twoja Mapa Drogowa

<!-- Spis treści generowany automatycznie przez JS -->

---

## 📚 Czym jest {readable_title}?

{readable_title} to jedno z kluczowych zagadnień w świecie nowoczesnych technologii internetowych. Rozumienie jego podstaw jest niezbędne dla każdego, kto chce efektywnie zarządzać swoją obecnością w sieci.

* Podstawowe komponenty
* Historia rozwoju
* Zastosowania w różnych branżach

## 💡 Dlaczego {readable_title} jest ważne?

W dzisiejszym cyfrowym świecie, gdzie każda sekunda ma znaczenie, a bezpieczeństwo danych jest priorytetem, prawidłowe wykorzystanie {readable_title.lower()} może stanowić o przewadze konkurencyjnej.

### Zwiększenie wydajności

Odpowiednio zoptymalizowane {readable_title.lower()} może znacząco przyspieszyć działanie Twojej strony czy aplikacji, co bezpośrednio przekłada się na zadowolenie użytkowników i lepsze wyniki biznesowe.

### Poprawa bezpieczeństwa

**Bezpieczeństwo danych** to jeden z najważniejszych aspektów każdego projektu internetowego. Implementacja najlepszych praktyk w zakresie {readable_title.lower()} pozwala na:

1. Ochronę przed popularnymi atakami
2. Zabezpieczenie danych użytkowników
3. Minimalizację ryzyka nieautoryzowanego dostępu

## 🔧 Jak skonfigurować {readable_title}?

Poprawna konfiguracja to klucz do sukcesu. Poniżej przedstawiamy proces krok po kroku:

1. **Przygotowanie środowiska:**
   ```bash
   apt-get update && apt-get upgrade -y
   ```

2. **Instalacja niezbędnych komponentów:**
   ```bash
   apt-get install example-package
   ```

3. **Konfiguracja podstawowych parametrów:**
   ```bash
   nano /etc/example/config.conf
   ```

> **Wskazówka:** Przed wprowadzeniem zmian w konfiguracji zawsze twórz kopię zapasową oryginalnych plików!

## 🚀 Najlepsze praktyki

Aby maksymalnie wykorzystać potencjał {readable_title.lower()}, warto stosować się do następujących praktyk:

* **Regularne aktualizacje** - zapewniają bezpieczeństwo i dostęp do najnowszych funkcji
* **Monitoring** - pozwala na szybkie wykrycie i rozwiązanie potencjalnych problemów
* **Optymalizacja** - dostosowanie parametrów do konkretnych potrzeb zwiększa wydajność

### ✅ Twoja Checklista:

* 🔍 Sprawdź aktualną wersję
* 🔄 Upewnij się, że automatyczne aktualizacje są włączone
* 🔒 Zweryfikuj ustawienia bezpieczeństwa
* 📊 Skonfiguruj podstawowe monitorowanie

## ❓ FAQ - Odpowiedzi na Twoje Pytania

**Jak często należy aktualizować {readable_title}?**  
Zalecamy sprawdzanie dostępności aktualizacji przynajmniej raz w miesiącu. Krytyczne aktualizacje bezpieczeństwa powinny być wdrażane niezwłocznie.

**Czy {readable_title} działa na wszystkich systemach operacyjnych?**  
Tak, większość rozwiązań jest kompatybilna z popularnymi systemami, jednak mogą występować różnice w konfiguracji.

**Jak rozwiązać problem X związany z {readable_title}?**  
Najczęstszą przyczyną tego problemu jest nieprawidłowa konfiguracja parametru Y. Sprawdź plik konfiguracyjny i upewnij się, że wartość jest ustawiona poprawnie.

## 🏁 Podsumowanie - Gotowy na Sukces?

{readable_title} to fundamentalny element nowoczesnej infrastruktury internetowej. Dzięki właściwej konfiguracji, regularnym aktualizacjom i stosowaniu najlepszych praktyk możesz znacząco zwiększyć wydajność, bezpieczeństwo i niezawodność swoich projektów online.

**🚀 Potrzebujesz profesjonalnego wsparcia?**

[Sprawdź ofertę hostingową IQHost](https://iqhost.pl/oferta)

*Nasi eksperci pomogą Ci zoptymalizować Twoją infrastrukturę i rozwiązać nawet najbardziej skomplikowane problemy techniczne.*
"""
    
    return content

def check_ollama_availability():
    """Sprawdza, czy Ollama API jest dostępne."""
    try:
        response = requests.get('http://mietek:11434/api/tags')
        if response.status_code == 200:
            models = response.json().get('models', [])
            if models:
                print(f"Dostępne modele Ollama: {', '.join([model['name'] for model in models])}")
                return True
            else:
                print("Ollama jest uruchomiona, ale nie znaleziono żadnych modeli.")
                return False
        else:
            print(f"Błąd podczas sprawdzania dostępności Ollama: {response.status_code} - {response.text}")
            return False
    except Exception as e:
        print(f"Nie można połączyć się z Ollama API: {str(e)}")
        print("Upewnij się, że Ollama jest zainstalowana i uruchomiona.")
        return False

def main():
    parser = argparse.ArgumentParser(description='Generuje artykuł dla bloga na podstawie numeru lub pełnej nazwy używając modeli Ollama.')
    parser.add_argument('article_input', type=str, nargs='?', help='Numer artykułu lub pełna nazwa artykułu do wygenerowania')
    parser.add_argument('--next', action='store_true', help='Wygeneruj pierwszy nieukończony artykuł z listy')
    parser.add_argument('--check', action='store_true', help='Tylko sprawdź czy artykuł istnieje, bez generowania treści')
    parser.add_argument('--sample-content', action='store_true', help='Użyj przykładowej treści zamiast generowania przez Ollama')
    parser.add_argument('--create-progress', action='store_true', help='Utwórz plik progress.md na podstawie katalogów, jeśli nie istnieje')
    parser.add_argument('--model', type=str, default='llama3', help='Nazwa modelu Ollama do użycia (domyślnie: llama3)')
    args = parser.parse_args()
    
    # Ścieżki
    blog_dir = '/home/stephen/claude/iqhost.pl/content/blog'
    
    # Sprawdź, czy Ollama jest dostępna
    if not args.sample_content and not args.check:
        if not check_ollama_availability():
            print("Kontynuowanie z przykładową treścią...")
            args.sample_content = True
    
    # Sprawdź, czy mamy plik progress.md, jeśli nie - utwórz go na podstawie katalogów
    progress_file = os.path.join(blog_dir, 'progress.md')
    if not os.path.exists(progress_file) or args.create_progress:
        progress_file = create_progress_file(blog_dir)
    
    # Sprawdź, czy chcemy wygenerować pierwszy nieukończony artykuł
    if args.next:
        article_title = get_first_todo_article(progress_file, blog_dir)
        print(f"Wybrany pierwszy nieukończony artykuł: {article_title}")
    elif args.article_input:
        # Sprawdźmy, czy artykuł istnieje w pliku progress.md
        try:
            article_title = get_article_title(args.article_input, progress_file)
            print(f"Znaleziono artykuł: {article_title}")
        except SystemExit:
            # Jeśli get_article_title zakończyło się błędem, pokaż zawartość pliku progress.md
            print("\nWypisuję fragment zawartości pliku progress.md:")
            with open(progress_file, 'r') as f:
                content = f.readlines()
                # Szukaj linii zawierających podobne wzorce
                for i, line in enumerate(content):
                    if args.article_input.split('.')[0] in line:
                        print(f"Linia {i+1}: {line.strip()}")
            sys.exit(1)
    else:
        parser.print_help()
        sys.exit(1)
    
    # Tryb diagnostyczny - tylko sprawdzenie
    if args.check:
        print(f"Artykuł {article_title} został znaleziony i może być wygenerowany.")
        sys.exit(0)
    
    print(f"Generowanie artykułu: {article_title}")
    
    # Utwórz katalog dla artykułu
    article_dir = create_article_directory(blog_dir, article_title)
    
    # Generowanie treści
    if args.sample_content:
        # Użyj przykładowej treści
        article_content = generate_sample_content(article_title)
    else:
        try:
            # Wygeneruj treść artykułu używając Ollama
            article_content = generate_article_content(article_title, args.model)
            
            if article_content is None:
                print("Nie udało się wygenerować treści artykułu. Użyję przykładowej treści.")
                article_content = generate_sample_content(article_title)
        except Exception as e:
            print(f"Błąd podczas generowania treści: {str(e)}")
            print("Używam przykładowej treści...")
            article_content = generate_sample_content(article_title)
    
    # Zapisz artykuł
    save_article(article_dir, article_title, article_content)
    print(f"Artykuł zapisany w: {os.path.join(article_dir, 'post.md')}")
    
    # Utwórz placeholder dla obrazu
    create_empty_image_placeholder(article_dir)
    print(f"Utworzono placeholder dla obrazu: {os.path.join(article_dir, 'main.png.txt')}")
    
    # Aktualizuj plik progress.md
    update_progress_file(progress_file, article_title)
    print(f"Plik progress.md zaktualizowany, artykuł oznaczony jako ukończony.")

if __name__ == '__main__':
    main()
