from flask import (
    Flask, render_template, request, send_file,
    redirect, url_for, abort
)
from jinja2 import TemplateNotFound
import yt_dlp, uuid, os

app = Flask(__name__)

# ================== BASIC SETTINGS ==================
DOWNLOAD_DIR = "downloads"
os.makedirs(DOWNLOAD_DIR, exist_ok=True)

# Set this if ffmpeg isn't on PATH, e.g. r"C:\tools\ffmpeg\bin"
FFMPEG_DIR = None
# ====================================================

# ---- metadata store for preview ----
# {file_id: {"title":..., "description":..., "uploader_name":..., "uploader_handle":...}}
DOWNLOAD_META = {}
# -----------------------------------


# ---------------------- helpers ----------------------
def _file_path(file_id: str) -> str:
    return os.path.join(DOWNLOAD_DIR, f"{file_id}.mp4")


def _ydl_opts(file_id: str) -> dict:
    """Minimal yt-dlp options (same behavior as your working script)."""
    out_pattern = os.path.join(DOWNLOAD_DIR, f"{file_id}.%(ext)s")
    return {
        "format": (
            "best[ext=mp4][acodec!=none]/"
            "bestvideo[ext=mp4]+bestaudio/best"
        ),
        "outtmpl": out_pattern,
        "merge_output_format": "mp4",
        "ffmpeg_location": FFMPEG_DIR,
        "quiet": True,
        "noplaylist": True,
    }


# ----------------------- routes -----------------------
@app.route("/", methods=["GET", "POST"])
def index():
    """
    GET  -> show form (index.html)
    POST -> download media, then redirect to /preview/<file_id>?title=...
    """
    if request.method == "POST":
        url = (request.form.get("url") or "").strip()
        if not url:
            return "<h3>Error:</h3><p>Please paste a TikTok link.</p>"

        file_id = uuid.uuid4().hex
        ydl_opts = _ydl_opts(file_id)

        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                info = ydl.extract_info(url, download=True)

            final_path = _file_path(file_id)
            if not os.path.isfile(final_path):
                raise FileNotFoundError("FFmpeg merge failed — check FFmpeg path.")

            title = info.get("title", "tiktok_video")

            # ---- capture real metadata for preview (ADDED description) ----
            description = info.get("description")
            uploader_name = info.get("uploader") or info.get("creator") or info.get("channel")
            uploader_handle = (
                info.get("uploader_id")
                or (info.get("uploader_url") or "").split("@")[-1].split("/")[0]
                or None
            )
            DOWNLOAD_META[file_id] = {
                "title": title,
                "description": description,            # <-- ADDED
                "uploader_name": uploader_name,
                "uploader_handle": uploader_handle,
            }
            # ----------------------------------------------------------------

            return redirect(url_for("preview", file_id=file_id, title=title))

        except Exception as err:
            return "<h3>Error:</h3><pre>{}</pre>".format(err)

    # GET
    return render_template("index.html")


@app.get("/preview")
def preview_from_query():
    """
    Supports your front-end's auto-redirect:
      /preview?url=...
    Downloads, then redirects to /preview/<file_id>.
    """
    url = (request.args.get("url") or "").strip()
    if not url:
        return redirect(url_for("index"))

    file_id = uuid.uuid4().hex
    ydl_opts = _ydl_opts(file_id)

    try:
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(url, download=True)

        final_path = _file_path(file_id)
        if not os.path.isfile(final_path):
            raise FileNotFoundError("FFmpeg merge failed — check FFmpeg path.")

        title = info.get("title", "TikTok Video")

        # ---- capture real metadata for preview (ADDED description) ----
        description = info.get("description")
        uploader_name = info.get("uploader") or info.get("creator") or info.get("channel")
        uploader_handle = (
            info.get("uploader_id")
            or (info.get("uploader_url") or "").split("@")[-1].split("/")[0]
            or None
        )
        DOWNLOAD_META[file_id] = {
            "title": title,
            "description": description,            # <-- ADDED
            "uploader_name": uploader_name,
            "uploader_handle": uploader_handle,
        }
        # ----------------------------------------------------------------

        return redirect(url_for("preview", file_id=file_id, title=title))
    except Exception as err:
        return "<h3>Error:</h3><pre>{}</pre>".format(err), 500


@app.get("/preview/<file_id>")
def preview(file_id):
    # read stored meta so template can show real title/description/user
    meta = DOWNLOAD_META.get(file_id, {})
    title = request.args.get("title", meta.get("title") or "TikTok Video")
    return render_template(
        "preview.html",
        file_id=file_id,
        title=title,
        description=meta.get("description"),          # <-- ADDED
        uploader_name=meta.get("uploader_name"),
        uploader_handle=meta.get("uploader_handle"),
    )


@app.get("/video/<file_id>")
def serve_video(file_id):
    path = _file_path(file_id)
    if not os.path.isfile(path):
        abort(404)
    # Inline streaming for the <video> tag
    return send_file(path, mimetype="video/mp4")


@app.get("/download/<file_id>")
def download_video(file_id):
    path = _file_path(file_id)
    if not os.path.isfile(path):
        abort(404)
    return send_file(path, as_attachment=True, download_name=f"{file_id}.mp4")


# --------- placeholder feature endpoints used in templates ---------
@app.get("/story-viewer")
def tiktok_downloader():
    # Placeholder: route exists so url_for('tiktok_downloader') works
    return redirect(url_for("index") + "?mode=story")


@app.get("/mp3")
def download_tiktok_mp3():
    # Placeholder: route exists so url_for('download_tiktok_mp3') works
    return redirect(url_for("index") + "?mode=mp3")


# --------- blueprint to satisfy url_for('photo.home') -----------
from flask import Blueprint
photo = Blueprint("photo", __name__)

@photo.route("/photo")
def home():
    # Placeholder redirect; replace with your real photo page later
    return redirect(url_for("index") + "?mode=photo")

app.register_blueprint(photo)


# --------- language endpoints referenced by index.html ----------
def _lang_redirect_factory(code: str):
    def _redir():
        # simple placeholder until you implement per-language pages
        return redirect(url_for("index") + f"?lang={code}")
    return _redir

# Use the exact endpoint names your template calls with url_for(...)
LANG_ENDPOINTS = {
    "fr_home": "fr",
    "ar_home": "ar",
    "ja_home": "ja",
    "th_home": "th",
    "id_home": "id",
    "du_home": "de",   # Deutsch alias used in your template
    "es_home": "es",
    "tr_home": "tr",
    "it_home": "it",
}
for ep, code in LANG_ENDPOINTS.items():
    if ep not in app.view_functions:
        app.add_url_rule(f"/{code}", ep, _lang_redirect_factory(code), methods=["GET"])


# ---------------- static pages used in footer ----------------
def _render_or_fallback(template_name: str, title: str, body: str):
    """Render template if present; otherwise show a minimal fallback page."""
    try:
        return render_template(template_name)
    except TemplateNotFound:
        return (
            "<!doctype html>"
            "<html><head><meta charset='utf-8'><title>{}</title>"
            "<meta name='viewport' content='width=device-width,initial-scale=1'></head>"
            "<body style=\"font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;"
            "max-width:800px;margin:40px auto;padding:0 16px;line-height:1.6\">"
            "<h1>{}</h1>"
            "<p>{}</p>"
            "<p style='margin-top:24px'><a href='{}'>← Back to Home</a></p>"
            "</body></html>".format(title, title, body, url_for("index"))
        )

@app.get("/contact")
def contact():
    return _render_or_fallback(
        "contact.html",
        "Contact Us",
        "This is a placeholder Contact page. Create templates/contact.html to customize."
    )

@app.get("/about")
def about():
    return _render_or_fallback(
        "about.html",
        "About",
        "This is a placeholder About page. Create templates/about.html to customize."
    )

@app.get("/terms")
def terms():
    return _render_or_fallback(
        "terms.html",
        "Terms & Conditions",
        "This is a placeholder Terms page. Create templates/terms.html to customize."
    )

@app.get("/privacy")
def privacy():
    return _render_or_fallback(
        "privacy.html",
        "Privacy Policy",
        "This is a placeholder Privacy page. Create templates/privacy.html to customize."
    )


# ---------------------- run ----------------------
if __name__ == "__main__":
    # host="0.0.0.0" if deploying
    app.run(debug=True)
