# ── 0) imports 
import os, traceback
from urllib.parse import urlparse, unquote
import aiomysql
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from openai import AsyncOpenAI
from dotenv import load_dotenv

#  환경변수 & OpenAI 
load_dotenv(override=True)
openai_client = AsyncOpenAI(api_key=os.getenv("OPENAI_API_KEY"))

#  FastAPI & CORS 
app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

# Pydantic 모델  
class ChatReq(BaseModel):
    messages: list[dict]

class UserInfo(BaseModel):
    session_id: str
    intro: str
    hobby: str
    goal: str
    skills: str

class CompanyInfo(BaseModel):
    session_id: str
    about: str
    culture: str
    skills: str
    welfare: str
    projects: str


# DB pull
db_pool = None

@app.on_event("startup")
async def startup():
    global db_pool
    try:
        # DATABASE_URL 우선
        dsn = os.getenv("DATABASE_URL")
        if dsn:
            p = urlparse(dsn)
            host, port = p.hostname, p.port or 3306
            user, pwd  = p.username, unquote(p.password or "")
            db_name    = p.path.lstrip("/")
        else:
            host = os.getenv("DB_HOST");    port = int(os.getenv("DB_PORT", "3306"))
            user = os.getenv("DB_USER");    pwd  = os.getenv("DB_PASSWORD")
            db_name = os.getenv("DB_NAME")

        db_pool = await aiomysql.create_pool(
            host=host, port=port, user=user, password=pwd,
            db=db_name, autocommit=True, charset="utf8mb4"
        )
    except Exception as e:
        traceback.print_exc()
        raise RuntimeError(f"Could not connect to database: {e}")

@app.on_event("shutdown")
async def shutdown():
    if db_pool:
        db_pool.close()
        await db_pool.wait_closed()

# 엔드포인트
@app.post("/goalskill/back/gpt-chat")
async def gpt_chat(req: ChatReq):
    try:
        res = await openai_client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=req.messages,
            temperature=0.7,
        )
        return {"reply": res.choices[0].message.content}
    except Exception as e:
        traceback.print_exc()
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/goalskill/back/save_userinfo")
async def save_userinfo(user_info: UserInfo):
    if not db_pool:
        raise HTTPException(503, "Database connection not available")

    sql = """
    INSERT INTO userinfo (session_id, intro, hobby, goal, skills)
    VALUES (%s,%s,%s,%s,%s)
    ON DUPLICATE KEY UPDATE
      intro=VALUES(intro),
      hobby=VALUES(hobby),
      goal=VALUES(goal),
      skills=VALUES(skills)
    """
    try:
        async with db_pool.acquire() as conn:
            async with conn.cursor() as cur:
                await cur.execute(sql, (
                    user_info.session_id,
                    user_info.intro,
                    user_info.hobby,
                    user_info.goal,
                    user_info.skills,
                ))
        return {"status": "success", "session_id": user_info.session_id}
    except Exception as e:
        traceback.print_exc()
        raise HTTPException(500, f"Database error: {e}")
    
@app.post("/goalskill/back/save_companyinfo")
async def save_companyinfo(info: CompanyInfo):
    if not db_pool:
        raise HTTPException(503, "DB connection not available")

    sql = """
    INSERT INTO companyinfo
      (session_id, about, culture, skills, welfare, projects)
    VALUES (%s,%s,%s,%s,%s,%s)
    ON DUPLICATE KEY UPDATE
      about=VALUES(about),
      culture=VALUES(culture),
      skills=VALUES(skills),
      welfare=VALUES(welfare),
      projects=VALUES(projects)
    """
    try:
        async with db_pool.acquire() as conn, conn.cursor() as cur:
            await cur.execute(sql, (
                info.session_id, info.about, info.culture,
                info.skills, info.welfare, info.projects
            ))
        return {"status": "success", "session_id": info.session_id}
    except Exception as e:
        traceback.print_exc()
        raise HTTPException(500, f"Database error: {e}")


@app.get("/goalskill/back/health")
async def health():
    return {"status": "ok"}
