"""
SI 프로젝트 보고서 생성 API

엔드포인트:
  GET /api/si/projects/{pid}/report/daily   — 일일 보고서
  GET /api/si/projects/{pid}/report/weekly  — 주간 보고서
  GET /api/si/projects/{pid}/report/monthly — 월간 보고서
  GET /api/si/projects/{pid}/report/status  — 현황 요약 (JSON)
  POST /api/si/projects/{pid}/report/send   — 메신저 자동 발송

쿼리 파라미터:
  format: excel | html | pdf | docx | pptx  (기본: html)
  send_messenger: true — 발송 후 파일도 반환
"""
from __future__ import annotations

import logging
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import Response, HTMLResponse
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

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

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/si/projects", tags=["si_report"])

_MIME = {
    "excel": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "html":  "text/html; charset=utf-8",
    "pdf":   "application/pdf",
    "docx":  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "pptx":  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
}

_EXT = {"excel": "xlsx", "html": "html", "pdf": "pdf", "docx": "docx", "pptx": "pptx"}


class SendRequest(BaseModel):
    room:        str = "ops"
    report_type: str = "weekly"
    fmt:         str = "excel"


async def _build_report(pid: int, report_type: str, fmt: str, db: AsyncSession):
    """보고서 생성 공통 헬퍼."""
    from core.si_report import generate_report
    try:
        content, mime, filename = await generate_report(pid, report_type, fmt, db)
        return content, mime, filename
    except ValueError as e:
        raise HTTPException(400, str(e))
    except Exception as e:
        logger.error("보고서 생성 오류: %s", e, exc_info=True)
        raise HTTPException(500, f"보고서 생성 실패: {str(e)[:200]}")


# ── 일일 보고서 ───────────────────────────────────────────────────────────────

@router.get("/{pid}/report/daily")
async def daily_report(
    pid:    int,
    format: str = Query("html", description="출력 형식: excel|html|pdf|docx|pptx"),
    db:     AsyncSession = Depends(get_db),
    _u:     User = Depends(get_current_user),
):
    content, mime, filename = await _build_report(pid, "daily", format, db)
    headers = {"Content-Disposition": f'attachment; filename="{filename}"'}
    if format == "html":
        return HTMLResponse(content.decode("utf-8") if isinstance(content, bytes) else content)
    return Response(content=content, media_type=mime, headers=headers)


# ── 주간 보고서 ───────────────────────────────────────────────────────────────

@router.get("/{pid}/report/weekly")
async def weekly_report(
    pid:    int,
    format: str = Query("excel"),
    db:     AsyncSession = Depends(get_db),
    _u:     User = Depends(get_current_user),
):
    content, mime, filename = await _build_report(pid, "weekly", format, db)
    headers = {"Content-Disposition": f'attachment; filename="{filename}"'}
    if format == "html":
        return HTMLResponse(content.decode("utf-8") if isinstance(content, bytes) else content)
    return Response(content=content, media_type=mime, headers=headers)


# ── 월간 보고서 ───────────────────────────────────────────────────────────────

@router.get("/{pid}/report/monthly")
async def monthly_report(
    pid:    int,
    format: str = Query("pptx"),
    db:     AsyncSession = Depends(get_db),
    _u:     User = Depends(get_current_user),
):
    content, mime, filename = await _build_report(pid, "monthly", format, db)
    headers = {"Content-Disposition": f'attachment; filename="{filename}"'}
    if format == "html":
        return HTMLResponse(content.decode("utf-8") if isinstance(content, bytes) else content)
    return Response(content=content, media_type=mime, headers=headers)


# ── 현황 요약 (JSON) ──────────────────────────────────────────────────────────

@router.get("/{pid}/report/status")
async def project_status(
    pid: int,
    db:  AsyncSession = Depends(get_db),
    _u:  User = Depends(get_current_user),
):
    """프로젝트 현황 JSON 요약 (대시보드용)."""
    from core.si_report import collect_project_data
    data = await collect_project_data(pid, db)
    proj = data["project"]
    return {
        "project_code":      proj.project_code,
        "project_name":      proj.project_name,
        "phase":             proj.phase,
        "health_status":     proj.health_status,
        "overall_progress":  data["overall_progress"],
        "budget_pct":        data["budget_pct"],
        "wbs_total":         data["wbs_total"],
        "wbs_done":          data["wbs_done"],
        "wbs_delayed":       data["wbs_delayed"],
        "issue_open":        data["issue_open"],
        "issue_closed":      data["issue_closed"],
        "high_risks":        len(data["high_risks"]),
        "overdue_deliverables": len(data["overdue_deliverables"]),
        "upcoming_milestones": [
            {"name": m.name, "target_date": str(m.target_date)}
            for m in data["upcoming_milestones"]
        ],
    }


# ── 메신저 자동 발송 ──────────────────────────────────────────────────────────

@router.post("/{pid}/report/send")
async def send_report(
    pid:  int,
    body: SendRequest,
    db:   AsyncSession = Depends(get_db),
    cu:   User = Depends(get_current_user),
):
    """보고서를 생성하여 메신저 채널로 자동 발송."""
    from core.si_report import collect_project_data, generate_excel, generate_html
    import os, httpx

    data = await collect_project_data(pid, db)
    proj = data["project"]

    rtype_name = {"daily": "일일", "weekly": "주간", "monthly": "월간"}.get(body.report_type, body.report_type)

    # 텍스트 요약 생성
    summary = (
        f"[{rtype_name} 보고서] {proj.project_name}\n"
        f"━━━━━━━━━━━━━━━━━━━━\n"
        f"단계: {proj.phase} | 건강상태: {proj.health_status}\n"
        f"진척률: {data['overall_progress']}% | 예산소진: {data['budget_pct']}%\n"
        f"WBS 완료: {data['wbs_done']}/{data['wbs_total']} | 지연: {data['wbs_delayed']}건\n"
        f"미결 이슈: {data['issue_open']}건 | 고위험: {len(data['high_risks'])}건\n"
        f"미제출 산출물: {len(data['overdue_deliverables'])}건\n"
        f"━━━━━━━━━━━━━━━━━━━━\n"
        f"상세: http://localhost:8001/si (SI 프로젝트 관리)"
    )

    # 메신저 발송
    messenger_url = os.getenv("MESSENGER_BASE_URL", "http://localhost:8002")
    try:
        async with httpx.AsyncClient(timeout=5.0) as client:
            await client.post(
                f"{messenger_url}/api/webhook/itsm",
                json={"room": body.room, "text": summary, "event": "project_report"},
            )
    except Exception:
        pass  # Fail-Safe

    return {
        "message": f"{rtype_name} 보고서 발송 완료",
        "room":    body.room,
        "summary": summary[:200],
    }
