#!/bin/bash
set -e

# 1) Очистить папку
cd ~/index.nexton.com.ua
rm -rf *

# 2) Создать нужную структуру
mkdir -p rss_monitor/{auth,tasks,templates,static}
touch rss_monitor/__init__.py \
      rss_monitor/cli.py \
      rss_monitor/models.py \
      rss_monitor/views.py \
      rss_monitor/auth/__init__.py \
      rss_monitor/auth/forms.py \
      rss_monitor/auth/views.py \
      rss_monitor/tasks/__init__.py \
      rss_monitor/tasks/scheduler.py \
      rss_monitor/templates/login.html \
      rss_monitor/templates/subscriptions.html \
      setup.py requirements.txt passenger_wsgi.py

# 3) Заполнить файлы

cat > setup.py << 'EOF2'
from setuptools import setup, find_packages

setup(
    name="rss_monitor",
    version="0.1.0",
    author="Ваша Компания",
    description="Веб-приложение для генерации RSS из любых страниц",
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        "Flask>=2.2",
        "Flask-Login",
        "Flask-Migrate",
        "Flask-SQLAlchemy",
        "feedgen",
        "requests",
        "beautifulsoup4",
        "Flask-WTF",
        "WTForms",
        "Flask-APScheduler",
    ],
    entry_points={
        "console_scripts": [
            "rss-monitor=rss_monitor.cli:main",
        ],
    },
)
EOF2

cat > requirements.txt << 'EOF2'
Flask>=2.2
Flask-Login
Flask-Migrate
Flask-SQLAlchemy
feedgen
requests
beautifulsoup4
Flask-WTF
WTForms
Flask-APScheduler
EOF2

cat > passenger_wsgi.py << 'EOF2'
import os, sys
sys.path.insert(0, os.path.dirname(__file__))

from rss_monitor import create_app
app = create_app()

@app.route("/")
def healthcheck():
    return "OK", 200

application = app
EOF2

cat > rss_monitor/__init__.py << 'EOF2'
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_apscheduler import APScheduler

db = SQLAlchemy()
migrate = Migrate()
login_manager = LoginManager()
scheduler = APScheduler()

def create_app():
    app = Flask(__name__, instance_relative_config=False)
    app.config.from_mapping(
        SECRET_KEY=os.getenv('SECRET_KEY'),
        SQLALCHEMY_DATABASE_URI=os.getenv('DATABASE_URL'),
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        SCHEDULER_API_ENABLED=True,
    )
    db.init_app(app)
    migrate.init_app(app, db)
    login_manager.init_app(app)
    scheduler.init_app(app)
    scheduler.start()
    from .auth.views import auth_bp
    app.register_blueprint(auth_bp)
    from .views import main_bp
    app.register_blueprint(main_bp)
    from .cli import register_cli_commands
    register_cli_commands(app)
    return app
EOF2

cat > rss_monitor/cli.py << 'EOF2'
import click
from flask.cli import with_appcontext
from werkzeug.security import generate_password_hash
from .models import db, User

def register_cli_commands(app):
    @app.cli.command('create-admin')
    @click.option('--username', prompt=True)
    @click.option('--password', prompt=True, hide_input=True, confirmation_prompt=True)
    @with_appcontext
    def create_admin(username, password):
        if User.query.filter_by(username=username).first():
            click.echo(f"User {username} exists")
            return
        user = User(username=username,
                    password_hash=generate_password_hash(password))
        db.session.add(user)
        db.session.commit()
        click.echo(f"Admin {username} created")

    @app.cli.command('run-scheduler')
    @with_appcontext
    def run_scheduler():
        click.echo("Scheduler runs inside the app process.")
EOF2

cat > rss_monitor/models.py << 'EOF2'
from datetime import datetime
from flask_login import UserMixin
from . import db, login_manager

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, nullable=False)
    password_hash = db.Column(db.String(128), nullable=False)

@login_manager.user_loader
def load_user(uid):
    return User.query.get(int(uid))

class Subscription(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    url = db.Column(db.String(512), nullable=False)
    selector = db.Column(db.String(256), nullable=True)
    last_hash = db.Column(db.String(64), nullable=True)

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    subscription_id = db.Column(db.Integer, db.ForeignKey('subscription.id'), nullable=False)
    title = db.Column(db.String(256), nullable=False)
    link = db.Column(db.String(512), nullable=False)
    snippet = db.Column(db.Text, nullable=True)
    pub_date = db.Column(db.DateTime, default=datetime.utcnow)
EOF2

cat > rss_monitor/views.py << 'EOF2'
from flask import Blueprint, render_template, request, redirect, url_for, Response
from flask_login import login_required, current_user
from . import db
from .models import Subscription, Item
from feedgen.feed import FeedGenerator

main_bp = Blueprint('main', __name__)

@main_bp.route('/subscriptions')
@login_required
def subscriptions():
    subs = Subscription.query.filter_by(user_id=current_user.id).all()
    return render_template('subscriptions.html', subs=subs)

@main_bp.route('/subscriptions/add', methods=['POST'])
@login_required
def add_subscription():
    url = request.form['url']
    selector = request.form.get('selector')
    sub = Subscription(user_id=current_user.id, url=url, selector=selector)
    db.session.add(sub); db.session.commit()
    return redirect(url_for('main.subscriptions'))

@main_bp.route('/rss.xml')
@login_required
def rss_feed():
    fg = FeedGenerator()
    fg.title(f"RSS для {current_user.username}")
    fg.link(href=request.url_root + 'rss.xml', rel='self')
    fg.description('Обновления ваших подписок')
    items = (Item.query.join(Subscription)
             .filter(Subscription.user_id == current_user.id)
             .order_by(Item.pub_date.desc()).limit(20))
    for i in items:
        fe = fg.add_entry()
        fe.id(i.link); fe.title(i.title)
        fe.link(href=i.link); fe.description(i.snippet)
        fe.pubDate(i.pub_date)
    xml = fg.rss_str(pretty=True)
    return Response(xml, mimetype='application/rss+xml')
EOF2

cat > rss_monitor/auth/forms.py << 'EOF2'
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Login')
EOF2

cat > rss_monitor/auth/views.py << 'EOF2'
from flask import Blueprint, render_template, redirect, url_for, flash
from flask_login import login_user, logout_user, login_required
from werkzeug.security import check_password_hash
from .forms import LoginForm
from ..models import User

auth_bp = Blueprint('auth', __name__)

@auth_bp.route('/login', methods=['GET','POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and check_password_hash(user.password_hash, form.password.data):
            login_user(user)
            return redirect(url_for('main.subscriptions'))
        flash('Invalid credentials', 'danger')
    return render_template('login.html', form=form)

@auth_bp.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('auth.login'))
EOF2

cat > rss_monitor/tasks/scheduler.py << 'EOF2'
from . import scheduler
from ..models import Subscription, Item, db
from bs4 import BeautifulSoup
import requests, hashlib
from datetime import datetime

def check_subscriptions():
    subs = Subscription.query.all()
    for sub in subs:
        r = requests.get(sub.url, timeout=10)
        text = (soup := BeautifulSoup(r.text, 'html.parser')).get_text() \
               if not sub.selector else soup.select_one(sub.selector).get_text()
        h = hashlib.sha256(text.encode()).hexdigest()
        if h != sub.last_hash:
            item = Item(subscription_id=sub.id,
                        title=soup.title.string if soup.title else sub.url,
                        link=sub.url, snippet=text[:200], pub_date=datetime.utcnow())
            db.session.add(item); sub.last_hash = h
    db.session.commit()

scheduler.add_job(id='check_subs', func=check_subscriptions,
                  trigger='interval', minutes=15)
EOF2

cat > rss_monitor/templates/login.html << 'EOF2'
<!doctype html>
<html><head><meta charset="utf-8"><title>Login</title></head><body>
<h1>Login</h1>
<form method="post">
  {{ form.hidden_tag() }}
  <p>{{ form.username.label }}<br>{{ form.username() }}</p>
  <p>{{ form.password.label }}<br>{{ form.password() }}</p>
  <p>{{ form.submit() }}</p>
  {% with messages = get_flashed_messages() %}
    {% for msg in messages %}<div style="color:red">{{ msg }}</div>{% endfor %}
  {% endwith %}
</form>
</body></html>
EOF2

cat > rss_monitor/templates/subscriptions.html << 'EOF2'
<!doctype html>
<html><head><meta charset="utf-8"><title>Subscriptions</title></head><body>
<h1>Your Subscriptions</h1>
<ul>{% for s in subs %}<li>{{ s.url }}</li>{% endfor %}</ul>
<h2>Add</h2>
<form action="{{ url_for('main.add_subscription') }}" method="post">
  <input name="url" placeholder="URL" size="50">
  <input name="selector" placeholder="CSS selector" size="30">
  <input type="submit" value="Add">
</form>
<p><a href="{{ url_for('auth.logout') }}">Logout</a></p>
</body></html>
EOF2

echo "Directory tree and files created."
