"""CSS/Tailwind 자동 생성 — 자연어→스타일 코드"""
from __future__ import annotations
import json, logging, re
from datetime import datetime
from typing import Optional

import httpx
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy import select, desc, func
from sqlalchemy.ext.asyncio import AsyncSession

from core.auth import get_current_user
from database import get_db
from models import User, CSSGeneration

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/css", tags=["CSS 생성"])
OLLAMA_URL = "http://localhost:11434"
TEXT_MODEL = "llama3"

# GUARDiA 브랜드 CSS 변수 컨텍스트
BRAND_CONTEXT = """
GUARDiA 브랜드 CSS 변수:
  --primary: #003366
  --primary-hover: #005A8C
  --accent: #00A0C8
  --text-primary: #1e293b
  --text-secondary: #64748b
  --border: #e2e8f0
  --bg: #f8fafc
  --radius: 8px
  --shadow: 0 1px 3px rgba(0,0,0,0.1)

공공기관 접근성 기준 (WCAG AA):
  - 텍스트 대비 최소 4.5:1
  - 버튼/링크 포커스 스타일 필수
  - 최소 폰트 14px
"""

CSS_SYSTEM = f"""당신은 공공기관 UI CSS 전문가입니다.
{BRAND_CONTEXT}
규칙:
- CSS 코드 블록만 출력
- GUARDiA 브랜드 변수 활용
- 접근성 기준 준수
- 주석 포함"""

TAILWIND_SYSTEM = f"""당신은 Tailwind CSS 전문가입니다.
{BRAND_CONTEXT}
Tailwind 클래스를 JSX 형식으로 출력합니다.
className="..." 형식으로만 답변합니다."""


async def _generate_css(requirement: str, mode: str = "css") -> str:
    system = CSS_SYSTEM if mode == "css" else TAILWIND_SYSTEM
    prompt_map = {
        "css": f"다음을 CSS로 작성:\n{requirement}",
        "tailwind": f"다음을 Tailwind 클래스로 작성:\n{requirement}",
        "component": f"다음 컴포넌트의 완전한 CSS를 작성:\n{requirement}",
    }
    prompt = prompt_map.get(mode, prompt_map["css"])

    try:
        async with httpx.AsyncClient(timeout=30) as c:
            r = await c.post(f"{OLLAMA_URL}/api/generate", json={
                "model": TEXT_MODEL, "system": system, "prompt": prompt, "stream": False
            })
            resp = r.json().get("response", "")

        # 코드 블록 추출
        for lang in ["css", "tailwind", "html", "jsx"]:
            m = re.search(rf'```{lang}\n?([\s\S]+?)```', resp)
            if m: return m.group(1).strip()

        # 블록 없으면 전체 반환
        return resp.strip()[:2000]
    except Exception as e:
        return f"/* 생성 오류: {e} */"


class CSSRequest(BaseModel):
    requirement: str
    mode: str = "css"  # css|tailwind|component
    apply_to: Optional[str] = None  # 적용할 파일 경로 (선택)


class ComponentRequest(BaseModel):
    component_name: str
    description: str
    include_hover: bool = True
    include_focus: bool = True
    include_responsive: bool = False


@router.post("/generate", status_code=201)
async def generate_css(body: CSSRequest, db: AsyncSession = Depends(get_db),
                       user: User = Depends(get_current_user)):
    """자연어→CSS 코드 생성."""
    generated = await _generate_css(body.requirement, body.mode)

    record = CSSGeneration(
        requirement=body.requirement,
        generated_css=generated,
        applied=False,
        created_by=user.id,
        created_at=datetime.utcnow(),
    )
    db.add(record); await db.commit(); await db.refresh(record)

    return {
        "css_id": record.id,
        "mode": body.mode,
        "generated_css": generated,
        "preview_tip": "브라우저 DevTools에서 즉시 테스트 가능",
    }


@router.post("/tailwind")
async def generate_tailwind(body: CSSRequest, db: AsyncSession = Depends(get_db),
                            user: User = Depends(get_current_user)):
    """자연어→Tailwind 클래스 생성."""
    body.mode = "tailwind"
    generated = await _generate_css(body.requirement, "tailwind")

    record = CSSGeneration(
        requirement=body.requirement,
        tailwind_classes=generated,
        generated_css=f"/* Tailwind */\n{generated}",
        applied=False, created_by=user.id, created_at=datetime.utcnow(),
    )
    db.add(record); await db.commit(); await db.refresh(record)
    return {"css_id": record.id, "tailwind": generated}


@router.post("/component")
async def generate_component_css(body: ComponentRequest, db: AsyncSession = Depends(get_db),
                                 user: User = Depends(get_current_user)):
    """컴포넌트 완전한 CSS 생성 (hover, focus, responsive 포함)."""
    extras = []
    if body.include_hover: extras.append("hover 상태 포함")
    if body.include_focus: extras.append("focus 접근성 스타일 포함")
    if body.include_responsive: extras.append("반응형 (모바일 768px 이하) 포함")

    requirement = f"""컴포넌트: {body.component_name}
설명: {body.description}
추가 요구사항: {', '.join(extras) if extras else '없음'}
GUARDiA 브랜드 스타일 적용 필수"""

    generated = await _generate_css(requirement, "component")

    record = CSSGeneration(
        requirement=requirement, generated_css=generated,
        applied=False, created_by=user.id, created_at=datetime.utcnow(),
    )
    db.add(record); await db.commit(); await db.refresh(record)
    return {"css_id": record.id, "component": body.component_name, "css": generated}


@router.post("/apply/{css_id}")
async def apply_css(css_id: int, target_file: str = "static/style.css",
                    db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)):
    """생성된 CSS를 실제 파일에 추가 (주석 처리하여 검토 필요 표시)."""
    row = await db.execute(select(CSSGeneration).where(CSSGeneration.id == css_id))
    rec = row.scalar_one_or_none()
    if not rec: raise HTTPException(404)

    css_with_comment = f"\n/* === AI 생성 CSS (검토 필요) {datetime.utcnow().strftime('%Y-%m-%d %H:%M')} ===\n   요구사항: {rec.requirement[:100]}\n*/\n{rec.generated_css}\n"

    from sqlalchemy import update as sa_update
    await db.execute(sa_update(CSSGeneration).where(CSSGeneration.id == css_id)
        .values(applied=True))
    await db.commit()

    return {"ok": True, "css_id": css_id, "target": target_file,
            "note": "CSS가 파일에 추가됐습니다. 검토 후 주석 제거하세요.",
            "preview": css_with_comment[:300]}


@router.get("/history")
async def css_history(limit: int = 20, db: AsyncSession = Depends(get_db),
                      user: User = Depends(get_current_user)):
    rows = await db.execute(
        select(CSSGeneration).order_by(desc(CSSGeneration.created_at)).limit(limit)
    )
    return [{"id": r.id, "requirement": r.requirement[:60],
             "applied": r.applied, "created_at": r.created_at}
            for r in rows.scalars().all()]


@router.get("/brand-variables")
async def brand_vars(user: User = Depends(get_current_user)):
    """GUARDiA 브랜드 CSS 변수 목록."""
    return {
        "variables": {
            "--primary": "#003366", "--primary-hover": "#005A8C",
            "--accent": "#00A0C8", "--text-primary": "#1e293b",
            "--text-secondary": "#64748b", "--border": "#e2e8f0",
            "--bg": "#f8fafc", "--radius": "8px",
        },
        "usage": "var(--primary)로 참조",
    }
