import os
import shutil
import json
from typing import List, Optional
# from fastapi import FastAPI, Form, File, UploadFile, HTTPException
from fastapi import APIRouter, Form, File, UploadFile, HTTPException
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, Text, insert
from sqlalchemy.orm import sessionmaker
from urllib.parse import quote_plus

# app = FastAPI(docs_url="/goal-skill-t/api/docs", openapi_url="/goal-skill-t/api/openapi.json")
router = APIRouter()

# --- 1. 데이터베이스 설정 (환경에 맞게 수정 필요) ---
# 예: mysql+pymysql://user:password@localhost/Theory_DB
# DB_URL = "mysql+pymysql://root:password@localhost/Theory_DB"
password = quote_plus("GOALSkill_99!@")
DB_URL = f"mysql+pymysql://GOALSkill:{password}@localhost/Theory_DB"
engine = create_engine(DB_URL)
metadata_obj = MetaData()
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# --- 2. 이미지 저장 경로 설정 ---
BASE_IMG_PATH = "/home/air/goalskill_t/back/img/"

@router.post("/goal-skill-t/api/save_content")
async def save_content(
    chapter_num: int = Form(...),      # 선택한 챕터 번호 (1, 2, ...)
    custom_chapter: str = Form(""),    # 챕터명 텍스트 (상단 입력값)
    blocks_json: str = Form(...),      # 프론트에서 보낸 블록 구조 JSON 문자열
    files: List[UploadFile] = File(None) # 업로드된 이미지 파일들
):
    """
    콘텐츠를 받아서 소제목(sub_title) 단위로 묶어 DB에 저장하고, 이미지를 저장함.
    """
    
    # 1. JSON 데이터 파싱
    try:
        blocks = json.loads(blocks_json)
    except json.JSONDecodeError:
        raise HTTPException(status_code=400, detail="Invalid JSON format")

    # 2. 동적 테이블 선택 (section_1, section_2 ...)
    table_name = f"section_{chapter_num}"
    
    # SQLAlchemy로 테이블 정의 반영 (이미 존재한다고 가정)
    try:
        table = Table(table_name, metadata_obj, autoload_with=engine)
    except Exception as e:
        # 테이블이 없을 경우를 대비한 예외처리 (혹은 직접 정의)
        # 여기서는 편의상 컬럼 구조가 고정되어 있다고 가정하고 동적 매핑
        table = Table(
            table_name, metadata_obj,
            Column('id', Integer, primary_key=True),
            Column('chapter', Text),
            Column('main_title', Text),
            Column('sub_title', Text),
            Column('theory_description', Text),
            Column('tip', Text),
            Column('img', Text),
            Column('img_description', Text),
            extend_existing=True
        )

    # 3. 이미지 저장용 디렉토리 확인 및 생성
    save_dir = os.path.join(BASE_IMG_PATH, f"section{chapter_num}")
    os.makedirs(save_dir, exist_ok=True)

    # 4. 데이터 파싱 및 그룹화 (Grouping Logic)
    rows_to_insert = []
    
    # 상태 유지 변수 (다음 소제목이 나오기 전까지 유지됨)
    current_context = {
        "chapter": custom_chapter, # 상단 챕터 입력값은 계속 유지될 수도 있음
        "main_title": None,
    }
    
    # 현재 조립 중인 행 데이터
    pending_row = {}
    
    # 파일 인덱스 카운터 (blocks 내의 image 타입 순서와 files 리스트 순서 매칭용)
    file_idx = 0 

    for block in blocks:
        b_type = block.get("type")
        b_value = block.get("value")

        # [로직] 대제목(Big Title)은 그냥 컨텍스트만 업데이트 (DB 저장은 소제목 나올 때)
        if b_type == "big-title":
            current_context["main_title"] = b_value

        # [로직] 소제목(Small Title)이 나오면? -> '새로운 행'의 시작 신호
        elif b_type == "small-title":
            # 이전까지 조립하던 행이 있다면 리스트에 추가 (pending_row가 비어있지 않다면)
            if pending_row and pending_row.get("sub_title"):
                rows_to_insert.append(pending_row)
            
            # 새로운 행 시작 (초기화)
            pending_row = {
                "chapter": current_context["chapter"],
                "main_title": current_context["main_title"],
                "sub_title": b_value, # 현재 소제목
                "theory_description": None,
                "tip": None,
                "img": None,
                "img_description": None
            }

        # [로직] 나머지 내용들은 현재 조립 중인 행(pending_row)에 추가
        elif pending_row: # 소제목이 션언된 이후에만 데이터 저장 가능
            
            if b_type == "theory":
                # 기존 내용이 있으면 줄바꿈 후 추가 (여러개일 경우)
                if pending_row["theory_description"]:
                    pending_row["theory_description"] += f"\n\n{b_value}"
                else:
                    pending_row["theory_description"] = b_value

            elif b_type == "advice":
                pending_row["tip"] = b_value

            elif b_type == "image-desc":
                pending_row["img_description"] = b_value

            elif b_type == "image":
                # 파일이 실제로 업로드 되었는지 확인
                if files and file_idx < len(files):
                    uploaded_file = files[file_idx]
                    file_idx += 1
                    
                    # 파일명 생성 로직 (1.png, 2.png, ...)
                    # 디렉토리 내 파일 개수를 세서 +1 하거나, 타임스탬프 사용.
                    # 요청사항: "숫자로 차례로"
                    existing_files = os.listdir(save_dir)
                    next_num = len(existing_files) + 1
                    
                    # 확장자 추출
                    ext = os.path.splitext(uploaded_file.filename)[1]
                    if not ext: ext = ".png" # 기본값
                    
                    new_filename = f"{next_num}{ext}"
                    file_path = os.path.join(save_dir, new_filename)
                    
                    # 파일 저장
                    with open(file_path, "wb") as buffer:
                        shutil.copyfileobj(uploaded_file.file, buffer)
                    
                    # DB에 저장할 경로 (절대경로)
                    pending_row["img"] = file_path

    # 반복문이 끝난 후, 마지막에 조립 중이던 행이 남아있으면 추가
    if pending_row and pending_row.get("sub_title"):
        rows_to_insert.append(pending_row)

    # 5. DB Insert 실행
    if not rows_to_insert:
        return {"status": "ok", "message": "저장할 데이터가 없습니다 (소제목 누락 등)."}

    with engine.connect() as conn:
        conn.execute(insert(table), rows_to_insert)
        conn.commit()

    return {"status": "success", "inserted_rows": len(rows_to_insert)}