"""
PIPE 스냅샷 관리 API 라우터

Cutting Plan 확정, 스냅샷 생성, 이슈 관리 준비 등의 기능 제공
"""

import logging
from typing import Dict, List, Optional, Any
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from pydantic import BaseModel

from ..database import get_db
from ..services.pipe_issue_snapshot_service import get_pipe_issue_snapshot_service, PipeIssueSnapshotService

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/pipe-snapshot", tags=["pipe-snapshot"])


# Pydantic 모델들
class FinalizeCuttingPlanRequest(BaseModel):
    job_no: str
    created_by: Optional[str] = "system"


class SnapshotStatusResponse(BaseModel):
    has_snapshot: bool
    snapshot_id: Optional[int] = None
    snapshot_name: Optional[str] = None
    is_locked: bool = False
    created_at: Optional[str] = None
    created_by: Optional[str] = None
    locked_at: Optional[str] = None
    locked_by: Optional[str] = None
    total_segments: int = 0
    total_drawings: int = 0
    drawing_issues_count: int = 0
    segment_issues_count: int = 0
    can_start_issue_management: bool = False
    message: str


class SnapshotSegmentsResponse(BaseModel):
    snapshot_id: int
    segments: List[Dict[str, Any]]
    total_count: int
    areas: List[str]
    drawings: List[str]


class FinalizeCuttingPlanResponse(BaseModel):
    success: bool
    snapshot_id: Optional[int] = None
    snapshot_name: Optional[str] = None
    total_segments: int = 0
    total_drawings: int = 0
    is_locked: bool = False
    locked_at: Optional[str] = None
    message: str
    next_action: Optional[str] = None


@router.post("/finalize-cutting-plan", response_model=FinalizeCuttingPlanResponse)
async def finalize_cutting_plan(
    request: FinalizeCuttingPlanRequest,
    db: Session = Depends(get_db)
):
    """
    Cutting Plan 확정 및 스냅샷 생성
    - 현재 단관 데이터를 스냅샷으로 고정
    - 이슈 관리 시작 가능 상태로 변경
    """
    try:
        service = get_pipe_issue_snapshot_service(db)
        result = service.create_and_lock_snapshot_on_finalize(
            request.job_no, 
            request.created_by
        )
        
        if not result["success"]:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=result["message"]
            )
        
        return FinalizeCuttingPlanResponse(**result)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to finalize cutting plan: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Cutting Plan 확정 실패: {str(e)}"
        )


@router.get("/status/{job_no}", response_model=SnapshotStatusResponse)
async def get_snapshot_status(
    job_no: str,
    db: Session = Depends(get_db)
):
    """
    작업의 스냅샷 상태 조회
    - 스냅샷 존재 여부
    - 잠금 상태
    - 이슈 관리 가능 여부
    """
    try:
        service = get_pipe_issue_snapshot_service(db)
        result = service.get_snapshot_info(job_no)
        
        return SnapshotStatusResponse(**result)
        
    except Exception as e:
        logger.error(f"Failed to get snapshot status: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"스냅샷 상태 조회 실패: {str(e)}"
        )


@router.get("/segments/{snapshot_id}", response_model=SnapshotSegmentsResponse)
async def get_snapshot_segments(
    snapshot_id: int,
    area: Optional[str] = None,
    drawing_name: Optional[str] = None,
    db: Session = Depends(get_db)
):
    """
    스냅샷된 단관 정보 조회
    - 구역별/도면별 필터링 가능
    - 이슈 관리 페이지에서 사용
    """
    try:
        service = get_pipe_issue_snapshot_service(db)
        
        # 단관 데이터 조회
        segments = service.get_snapshot_segments(snapshot_id, area, drawing_name)
        
        # 사용 가능한 구역/도면 목록
        areas = service.get_available_areas(snapshot_id)
        drawings = service.get_available_drawings(snapshot_id, area)
        
        return SnapshotSegmentsResponse(
            snapshot_id=snapshot_id,
            segments=segments,
            total_count=len(segments),
            areas=areas,
            drawings=drawings
        )
        
    except Exception as e:
        logger.error(f"Failed to get snapshot segments: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"스냅샷 단관 조회 실패: {str(e)}"
        )


@router.get("/areas/{snapshot_id}")
async def get_available_areas(
    snapshot_id: int,
    db: Session = Depends(get_db)
):
    """스냅샷의 사용 가능한 구역 목록 조회"""
    try:
        service = get_pipe_issue_snapshot_service(db)
        areas = service.get_available_areas(snapshot_id)
        
        return {
            "snapshot_id": snapshot_id,
            "areas": areas,
            "total_count": len(areas)
        }
        
    except Exception as e:
        logger.error(f"Failed to get available areas: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"구역 목록 조회 실패: {str(e)}"
        )


@router.get("/drawings/{snapshot_id}")
async def get_available_drawings(
    snapshot_id: int,
    area: Optional[str] = None,
    db: Session = Depends(get_db)
):
    """스냅샷의 사용 가능한 도면 목록 조회"""
    try:
        service = get_pipe_issue_snapshot_service(db)
        drawings = service.get_available_drawings(snapshot_id, area)
        
        return {
            "snapshot_id": snapshot_id,
            "area": area,
            "drawings": drawings,
            "total_count": len(drawings)
        }
        
    except Exception as e:
        logger.error(f"Failed to get available drawings: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"도면 목록 조회 실패: {str(e)}"
        )


@router.get("/revision-protection/{job_no}")
async def check_revision_protection(
    job_no: str,
    db: Session = Depends(get_db)
):
    """
    리비전 보호 상태 확인
    - 잠긴 스냅샷이 있으면 리비전 영향 받지 않음
    """
    try:
        service = get_pipe_issue_snapshot_service(db)
        result = service.check_revision_protection(job_no)
        
        return result
        
    except Exception as e:
        logger.error(f"Failed to check revision protection: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"리비전 보호 상태 확인 실패: {str(e)}"
        )


@router.delete("/snapshot/{snapshot_id}")
async def delete_snapshot(
    snapshot_id: int,
    force: bool = False,
    db: Session = Depends(get_db)
):
    """
    스냅샷 삭제 (개발/테스트용)
    - force=True: 강제 삭제 (이슈 데이터 포함)
    - force=False: 이슈가 없는 경우만 삭제
    """
    try:
        from ..models import PipeIssueSnapshot, PipeDrawingIssue, PipeSegmentIssue
        
        # 스냅샷 존재 확인
        snapshot = db.query(PipeIssueSnapshot).filter(
            PipeIssueSnapshot.id == snapshot_id
        ).first()
        
        if not snapshot:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="스냅샷을 찾을 수 없습니다."
            )
        
        # 이슈 데이터 확인
        drawing_issues_count = db.query(PipeDrawingIssue).filter(
            PipeDrawingIssue.snapshot_id == snapshot_id
        ).count()
        
        segment_issues_count = db.query(PipeSegmentIssue).filter(
            PipeSegmentIssue.snapshot_id == snapshot_id
        ).count()
        
        total_issues = drawing_issues_count + segment_issues_count
        
        if total_issues > 0 and not force:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"이슈 데이터가 {total_issues}개 있습니다. force=true로 강제 삭제하거나 이슈를 먼저 정리해주세요."
            )
        
        # 스냅샷 삭제 (CASCADE로 관련 데이터 자동 삭제)
        db.delete(snapshot)
        db.commit()
        
        return {
            "success": True,
            "message": f"스냅샷 '{snapshot.snapshot_name}'이 삭제되었습니다.",
            "deleted_snapshot_id": snapshot_id,
            "deleted_issues_count": total_issues
        }
        
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        logger.error(f"Failed to delete snapshot: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"스냅샷 삭제 실패: {str(e)}"
        )


@router.get("/job/{job_no}/history")
async def get_snapshot_history(
    job_no: str,
    db: Session = Depends(get_db)
):
    """작업별 스냅샷 이력 조회"""
    try:
        from ..models import PipeIssueSnapshot
        
        snapshots = db.query(PipeIssueSnapshot).filter(
            PipeIssueSnapshot.job_no == job_no
        ).order_by(PipeIssueSnapshot.created_at.desc()).all()
        
        history = []
        for snapshot in snapshots:
            history.append({
                "snapshot_id": snapshot.id,
                "snapshot_name": snapshot.snapshot_name,
                "is_active": snapshot.is_active,
                "is_locked": snapshot.is_locked,
                "created_at": snapshot.created_at.isoformat() if snapshot.created_at else None,
                "created_by": snapshot.created_by,
                "locked_at": snapshot.locked_at.isoformat() if snapshot.locked_at else None,
                "locked_by": snapshot.locked_by,
                "total_segments": snapshot.total_segments,
                "total_drawings": snapshot.total_drawings
            })
        
        return {
            "job_no": job_no,
            "total_snapshots": len(history),
            "history": history
        }
        
    except Exception as e:
        logger.error(f"Failed to get snapshot history: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"스냅샷 이력 조회 실패: {str(e)}"
        )
