import os
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
from flask import Flask, render_template
from config import Config
from app.extensions import db, migrate, login_manager, csrf, limiter

def create_app(config_class=Config):
    load_dotenv()
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object(config_class)
    Path(app.instance_path).mkdir(parents=True, exist_ok=True)
    Path(app.config["UPLOAD_FOLDER"]).mkdir(parents=True, exist_ok=True)

    db.init_app(app)
    migrate.init_app(app, db)
    login_manager.init_app(app)
    csrf.init_app(app)
    limiter.init_app(app)
    login_manager.login_view = "auth.login"
    login_manager.login_message = "Silakan masuk untuk mengakses halaman tersebut."
    login_manager.login_message_category = "warning"

    from app import models
    from app.public import bp as public_bp
    from app.auth import bp as auth_bp
    from app.admin import bp as admin_bp
    app.register_blueprint(public_bp)
    app.register_blueprint(auth_bp)
    app.register_blueprint(admin_bp)

    @app.context_processor
    def global_template_values():
        from app.models import Menu, SiteSetting
        settings = {s.key: s.value for s in SiteSetting.query.all()}
        menus = Menu.query.filter_by(active=True, location="header", parent_id=None).order_by(Menu.sort_order).all()
        from datetime import datetime
        return {"site_settings": settings, "header_menus": menus, "now_year": datetime.utcnow().year}

    @app.errorhandler(404)
    def not_found(error):
        return render_template("errors/404.html"), 404

    @app.errorhandler(500)
    def server_error(error):
        db.session.rollback()
        return render_template("errors/500.html"), 500

    @app.cli.command("init-data")
    def init_data():
        from app.models import Role, NewsCategory, SiteSetting, Menu
        for name, desc in [
            ("super_admin", "Akses penuh"), ("content_admin", "Mengelola konten"),
            ("editor", "Menulis dan mengirim konten"), ("contributor", "Membuat draft")
        ]:
            if not Role.query.filter_by(name=name).first():
                db.session.add(Role(name=name, description=desc))
        for name, slug in [("Akademik","akademik"),("Kegiatan","kegiatan"),("Prestasi","prestasi"),("Penelitian","penelitian")]:
            if not NewsCategory.query.filter_by(slug=slug).first():
                db.session.add(NewsCategory(name=name, slug=slug))
        defaults = {
            "program_name": "Pendidikan Teknik Informatika",
            "tagline": "Membangun Pendidik dan Inovator Digital Masa Depan",
            "email": "pti@example.ac.id",
            "address": "Alamat kampus dapat diperbarui melalui dashboard admin.",
            "hero_title": "Membangun Pendidik dan Inovator Digital Masa Depan",
            "hero_description": "Mengembangkan kompetensi pendidikan, teknologi, dan inovasi digital untuk menjawab tantangan masa depan."
        }
        for key, value in defaults.items():
            if not SiteSetting.query.filter_by(key=key).first():
                db.session.add(SiteSetting(key=key, value=value))
        if not Menu.query.first():
            for i, (label, url) in enumerate([("Beranda","/"),("Profil","/profil"),("Berita","/berita"),("Aktivitas","/aktivitas"),("Dosen","/dosen"),("Akademik","/akademik"),("Kontak","/kontak")]):
                db.session.add(Menu(label=label, url=url, sort_order=i, location="header"))
        db.session.commit()
        print("Data awal berhasil dibuat.")

    @app.cli.command("create-admin")
    def create_admin():
        import getpass
        from app.models import User, Role
        username = input("Username Super Admin: ").strip()
        email = input("Email Super Admin: ").strip().lower()
        full_name = input("Nama lengkap: ").strip()
        password = getpass.getpass("Password (minimal 12 karakter): ")
        if len(password) < 12:
            print("Password minimal 12 karakter."); return
        if User.query.filter((User.username == username) | (User.email == email)).first():
            print("Username atau email sudah digunakan."); return
        role = Role.query.filter_by(name="super_admin").first()
        if role is None:
            print("Jalankan 'flask init-data' terlebih dahulu."); return
        user = User(username=username, email=email, full_name=full_name)
        user.set_password(password)
        user.roles.append(role)
        db.session.add(user); db.session.commit()
        print("Super Admin berhasil dibuat.")

    return app
