# -*- coding: utf-8 -*-
import os
import ftplib
import posixpath
import requests
from datetime import datetime


def clean_value(value):
    return str(value or "").strip()


def normalize_remote_path(path):
    path = clean_value(path).replace("\\", "/")
    while "//" in path:
        path = path.replace("//", "/")
    return path.strip("/")


def join_remote(*parts):
    return "/".join([normalize_remote_path(p) for p in parts if clean_value(p)])


def get_app_setting(conn, setting_key, default=""):
    try:
        with conn.cursor() as cur:
            cur.execute("""
                SELECT setting_value
                FROM blog_app_settings
                WHERE setting_key = %s
                LIMIT 1
            """, (setting_key,))
            row = cur.fetchone()
        return clean_value(row.get("setting_value")) if row else default
    except Exception:
        return default


def get_cafe24_cdn_config(conn):
    return {
        "enabled": get_app_setting(conn, "cafe24_cdn_enabled", "0") in ["1", "true", "yes", "on"],
        "ftp_host": get_app_setting(conn, "cafe24_ftp_host", ""),
        "ftp_port": int(get_app_setting(conn, "cafe24_ftp_port", "21") or 21),
        "ftp_user": get_app_setting(conn, "cafe24_ftp_user", ""),
        "ftp_password": get_app_setting(conn, "cafe24_ftp_password", ""),
        "ftp_root_dir": normalize_remote_path(get_app_setting(conn, "cafe24_ftp_root_dir", "www")),
        "cdn_base_url": get_app_setting(conn, "cafe24_cdn_base_url", "").rstrip("/"),
    }


def ensure_ftp_dir(ftp, remote_dir):
    remote_dir = normalize_remote_path(remote_dir)
    if not remote_dir:
        return

    current = ""
    for part in remote_dir.split("/"):
        current = f"{current}/{part}" if current else part
        try:
            ftp.cwd("/" + current)
        except Exception:
            try:
                ftp.mkd("/" + current)
            except Exception:
                pass
            ftp.cwd("/" + current)


def ftp_upload_file(config, local_path, remote_path):
    local_path = clean_value(local_path).replace("\\", "/")
    remote_path = normalize_remote_path(remote_path)

    if not os.path.exists(local_path):
        raise Exception(f"로컬 파일이 없습니다: {local_path}")

    remote_dir = posixpath.dirname(remote_path)
    remote_name = posixpath.basename(remote_path)

    ftp = ftplib.FTP()
    ftp.connect(config["ftp_host"], config["ftp_port"], timeout=30)
    ftp.login(config["ftp_user"], config["ftp_password"])
    ftp.encoding = "utf-8"

    try:
        ensure_ftp_dir(ftp, remote_dir)
        ftp.cwd("/" + remote_dir)
        with open(local_path, "rb") as f:
            ftp.storbinary(f"STOR {remote_name}", f)
    finally:
        try:
            ftp.quit()
        except Exception:
            ftp.close()


def build_header_remote_path(article_no, filename):
    now = datetime.now()
    return join_remote(
        "real_auto",
        "header_images",
        now.strftime("%Y"),
        now.strftime("%m"),
        clean_value(article_no) or "common",
        clean_value(filename) or f"header_{article_no}.png"
    )


def build_cdn_url(config, remote_path):
    remote_path = normalize_remote_path(remote_path)
    root = normalize_remote_path(config.get("ftp_root_dir") or "")

    if root and remote_path.startswith(root + "/"):
        public_path = remote_path[len(root) + 1:]
    else:
        public_path = remote_path

    return config["cdn_base_url"].rstrip("/") + "/" + public_path


def verify_cdn_url(cdn_url):
    headers = {"User-Agent": "Mozilla/5.0", "Cache-Control": "no-cache"}

    last_status = None
    last_error = ""

    for _ in range(5):
        try:
            res = requests.get(cdn_url, headers=headers, timeout=15)
            last_status = res.status_code
            if res.status_code == 200 and len(res.content) > 1024:
                return True, res.status_code, len(res.content)
        except Exception as e:
            last_error = str(e)

    return False, last_status, last_error


def upload_header_image_to_cafe24(conn, article_no, local_path, filename=""):
    config = get_cafe24_cdn_config(conn)

    if not config["enabled"]:
        raise Exception("Cafe24 CDN 사용 설정이 꺼져 있습니다.")

    for key in ["ftp_host", "ftp_user", "ftp_password", "cdn_base_url"]:
        if not config.get(key):
            raise Exception(f"Cafe24 CDN 설정 누락: {key}")

    if not filename:
        filename = os.path.basename(local_path)

    public_path = build_header_remote_path(article_no, filename)
    remote_path = join_remote(config["ftp_root_dir"], public_path)

    ftp_upload_file(config, local_path, remote_path)

    cdn_url = build_cdn_url(config, remote_path)
    ok, status_code, size_or_error = verify_cdn_url(cdn_url)

    if not ok:
        raise Exception(f"CDN URL 확인 실패: {cdn_url}, status={status_code}, detail={size_or_error}")

    return {
        "ok": True,
        "local_path": local_path.replace("\\", "/"),
        "remote_path": remote_path,
        "public_path": public_path,
        "cdn_url": cdn_url,
        "http_status": status_code,
        "size": size_or_error,
    }
