from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from sqlalchemy import text, func
from typing import List, Optional
from datetime import datetime

from database.database import get_db
from database.models import Issue, IssueStatus, User, UserRole, ReviewStatus
from database import schemas
from routers.auth import get_current_user, get_current_admin
from routers.page_permissions import check_page_access
from services.file_service import save_base64_image, delete_file

router = APIRouter(prefix="/api/issues", tags=["issues"])

@router.post("/", response_model=schemas.Issue)
async def create_issue(
    issue: schemas.IssueCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):

    # 이미지 저장 (최대 5장)
    photo_paths = {}
    for i in range(1, 6):
        photo_field = f"photo{i if i > 1 else ''}"
        path_field = f"photo_path{i if i > 1 else ''}"
        photo_data = getattr(issue, photo_field, None)
        if photo_data:
            photo_paths[path_field] = save_base64_image(photo_data)
        else:
            photo_paths[path_field] = None

    # Issue 생성
    db_issue = Issue(
        category=issue.category,
        description=issue.description,
        location_info=issue.location_info,
        photo_path=photo_paths.get('photo_path'),
        photo_path2=photo_paths.get('photo_path2'),
        photo_path3=photo_paths.get('photo_path3'),
        photo_path4=photo_paths.get('photo_path4'),
        photo_path5=photo_paths.get('photo_path5'),
        reporter_id=current_user.id,
        project_id=issue.project_id,
        status=IssueStatus.new
    )
    db.add(db_issue)
    db.commit()
    db.refresh(db_issue)
    return db_issue

@router.get("/", response_model=List[schemas.Issue])
async def read_issues(
    skip: int = 0,
    limit: int = 100,
    status: Optional[IssueStatus] = None,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    query = db.query(Issue)
    
    # 권한별 조회 제한
    if current_user.role == UserRole.admin:
        # 관리자는 모든 이슈 조회 가능
        pass
    else:
        # 일반 사용자는 본인이 등록한 이슈만 조회 가능
        query = query.filter(Issue.reporter_id == current_user.id)
    
    if status:
        query = query.filter(Issue.status == status)
    
    # 최신순 정렬 (report_date 기준)
    issues = query.order_by(Issue.report_date.desc()).offset(skip).limit(limit).all()
    return issues

@router.get("/admin/all", response_model=List[schemas.Issue])
async def read_all_issues_admin(
    skip: int = 0,
    limit: int = 100,
    status: Optional[IssueStatus] = None,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """이슈 관리 권한이 있는 사용자: 모든 부적합 조회"""
    # 이슈 관리 페이지 권한 확인 (관리함, 폐기함 등에서 사용)
    from routers.page_permissions import check_page_access
    
    # 관리자이거나 이슈 관리 권한이 있는 사용자만 접근 가능
    if (current_user.role != 'admin' and 
        not check_page_access(current_user.id, 'issues_manage', db) and
        not check_page_access(current_user.id, 'issues_inbox', db) and
        not check_page_access(current_user.id, 'issues_management', db) and
        not check_page_access(current_user.id, 'issues_archive', db)):
        raise HTTPException(status_code=403, detail="이슈 관리 권한이 없습니다.")
    
    query = db.query(Issue)
    
    if status:
        query = query.filter(Issue.status == status)
    
    # 최신순 정렬 (report_date 기준)
    issues = query.order_by(Issue.report_date.desc()).offset(skip).limit(limit).all()
    return issues

@router.get("/{issue_id}", response_model=schemas.Issue)
async def read_issue(
    issue_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="Issue not found")
    
    # 권한별 조회 제한
    if current_user.role != UserRole.admin and issue.reporter_id != current_user.id:
        raise HTTPException(
            status_code=403, 
            detail="본인이 등록한 부적합만 조회할 수 있습니다."
        )
    
    return issue

@router.put("/{issue_id}", response_model=schemas.Issue)
async def update_issue(
    issue_id: int,
    issue_update: schemas.IssueUpdate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="Issue not found")
    
    # 권한 확인
    if current_user.role == UserRole.user and issue.reporter_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not authorized to update this issue")
    
    # 업데이트
    update_data = issue_update.dict(exclude_unset=True)

    # 프로젝트 변경 시 sequence_no 재계산
    if "project_id" in update_data and update_data["project_id"] != issue.project_id:
        if issue.review_status and issue.review_status != ReviewStatus.in_progress:
            raise HTTPException(status_code=400, detail="진행 중 상태에서만 프로젝트를 변경할 수 있습니다")
        try:
            new_seq = db.execute(text("SELECT generate_project_sequence_no(:pid)"),
                                 {"pid": update_data["project_id"]}).scalar()
            update_data["project_sequence_no"] = new_seq
        except Exception:
            max_seq = db.query(func.coalesce(func.max(Issue.project_sequence_no), 0)).filter(
                Issue.project_id == update_data["project_id"]
            ).scalar()
            update_data["project_sequence_no"] = max_seq + 1

    # 사진 업데이트 처리 (최대 5장) - 새 사진 저장 후 기존 사진 삭제 (안전)
    old_photos_to_delete = []
    for i in range(1, 6):
        photo_field = f"photo{i if i > 1 else ''}"
        path_field = f"photo_path{i if i > 1 else ''}"

        if photo_field in update_data:
            existing_path = getattr(issue, path_field, None)

            # 새 사진 저장
            if update_data[photo_field]:
                new_path = save_base64_image(update_data[photo_field])
                update_data[path_field] = new_path
                # 새 사진 저장 성공 시에만 기존 사진 삭제 예약
                if new_path and existing_path:
                    old_photos_to_delete.append(existing_path)
            else:
                update_data[path_field] = None
                if existing_path:
                    old_photos_to_delete.append(existing_path)

            # photo 필드는 제거 (DB에는 photo_path만 저장)
            del update_data[photo_field]
    
    # work_hours가 입력되면 자동으로 상태를 complete로 변경
    if "work_hours" in update_data and update_data["work_hours"] > 0:
        if issue.status == IssueStatus.new:
            update_data["status"] = IssueStatus.complete
    
    for field, value in update_data.items():
        setattr(issue, field, value)
    
    db.commit()
    db.refresh(issue)

    # DB 커밋 성공 후 기존 사진 파일 삭제
    for old_path in old_photos_to_delete:
        try:
            delete_file(old_path)
        except Exception:
            pass

    return issue

@router.delete("/{issue_id}")
async def delete_issue(
    issue_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    from database.models import DeletionLog
    import json

    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="Issue not found")

    # 권한 확인 (관리자 또는 본인이 등록한 경우 삭제 가능)
    if current_user.role != UserRole.admin and issue.reporter_id != current_user.id:
        raise HTTPException(status_code=403, detail="본인이 등록한 부적합만 삭제할 수 있습니다.")

    # 이 이슈를 중복 대상으로 참조하는 다른 이슈들의 참조 제거
    referencing_issues = db.query(Issue).filter(Issue.duplicate_of_issue_id == issue_id).all()
    if referencing_issues:
        for ref_issue in referencing_issues:
            ref_issue.duplicate_of_issue_id = None
        db.flush()  # 참조 제거를 먼저 커밋

    # 삭제 로그 생성 (삭제 전 데이터 저장)
    issue_data = {
        "id": issue.id,
        "category": issue.category.value if issue.category else None,
        "description": issue.description,
        "status": issue.status.value if issue.status else None,
        "reporter_id": issue.reporter_id,
        "project_id": issue.project_id,
        "report_date": issue.report_date.isoformat() if issue.report_date else None,
        "work_hours": issue.work_hours,
        "detail_notes": issue.detail_notes,
        "photo_path": issue.photo_path,
        "photo_path2": issue.photo_path2,
        "review_status": issue.review_status.value if issue.review_status else None,
        "solution": issue.solution,
        "responsible_department": issue.responsible_department.value if issue.responsible_department else None,
        "responsible_person": issue.responsible_person,
        "expected_completion_date": issue.expected_completion_date.isoformat() if issue.expected_completion_date else None,
        "actual_completion_date": issue.actual_completion_date.isoformat() if issue.actual_completion_date else None,
    }

    deletion_log = DeletionLog(
        entity_type="issue",
        entity_id=issue.id,
        entity_data=issue_data,
        deleted_by_id=current_user.id,
        reason=f"사용자 {current_user.username}에 의해 삭제됨"
    )
    db.add(deletion_log)

    # 이미지 파일 삭제 (신고 사진 최대 5장)
    for i in range(1, 6):
        path_field = f"photo_path{i if i > 1 else ''}"
        path = getattr(issue, path_field, None)
        if path:
            delete_file(path)

    # 완료 사진 삭제 (최대 5장)
    for i in range(1, 6):
        path_field = f"completion_photo_path{i if i > 1 else ''}"
        path = getattr(issue, path_field, None)
        if path:
            delete_file(path)

    db.delete(issue)
    db.commit()
    return {"detail": "Issue deleted successfully", "logged": True}

@router.post("/{issue_id}/opinion")
async def add_opinion(
    issue_id: int,
    opinion_request: schemas.OpinionRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    의견 제시 — 로그인한 모든 사용자가 사용 가능 (권한 체크 없음)
    solution 필드에 의견을 추가합니다.
    """
    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="부적합을 찾을 수 없습니다.")

    # 새 의견 형식: [작성자] (날짜시간)\n내용
    now = datetime.now()
    date_str = now.strftime("%Y. %m. %d. %H:%M")
    author = current_user.full_name or current_user.username
    new_opinion = f"[{author}] ({date_str})\n{opinion_request.opinion}"

    # 기존 solution에 추가 (최신이 위로)
    separator = "─" * 50
    if issue.solution:
        issue.solution = f"{new_opinion}\n{separator}\n{issue.solution}"
    else:
        issue.solution = new_opinion

    db.commit()
    db.refresh(issue)

    return {
        "message": "의견이 추가되었습니다.",
        "issue_id": issue.id
    }

@router.get("/stats/summary")
async def get_issue_stats(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """이슈 통계 조회"""
    query = db.query(Issue)
    
    # 일반 사용자는 자신의 이슈만
    if current_user.role == UserRole.user:
        query = query.filter(Issue.reporter_id == current_user.id)
    
    total = query.count()
    new = query.filter(Issue.status == IssueStatus.new).count()
    progress = query.filter(Issue.status == IssueStatus.progress).count()
    complete = query.filter(Issue.status == IssueStatus.complete).count()
    
    return {
        "total": total,
        "new": new,
        "progress": progress,
        "complete": complete
    }

@router.put("/{issue_id}/management")
async def update_issue_management(
    issue_id: int,
    management_update: schemas.ManagementUpdateRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    관리함에서 이슈의 관리 관련 필드들을 업데이트합니다.
    """
    # 관리함 페이지 권한 확인
    if not (current_user.role == UserRole.admin or check_page_access(current_user.id, 'issues_management', db)):
        raise HTTPException(status_code=403, detail="관리함 접근 권한이 없습니다.")
    
    # 이슈 조회
    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="부적합을 찾을 수 없습니다.")
    
    # 관리함에서만 수정 가능한 필드들만 업데이트
    update_data = management_update.dict(exclude_unset=True)
    # 완료 사진 처리 (최대 5장)
    completion_photo_fields = []
    for i in range(1, 6):
        photo_field = f"completion_photo{i if i > 1 else ''}"
        path_field = f"completion_photo_path{i if i > 1 else ''}"

        if photo_field in update_data and update_data[photo_field]:
            completion_photo_fields.append(photo_field)
            try:
                # 기존 사진 삭제
                existing_path = getattr(issue, path_field, None)
                if existing_path:
                    delete_file(existing_path)

                # 새 사진 저장
                new_path = save_base64_image(update_data[photo_field], "completion")
                setattr(issue, path_field, new_path)
            except Exception as e:
                raise HTTPException(status_code=400, detail=f"완료 사진 저장 실패: {str(e)}")

    # 나머지 필드 처리 (완료 사진 제외)
    for field, value in update_data.items():
        if field not in completion_photo_fields:
            try:
                setattr(issue, field, value)
            except Exception as e:
                raise HTTPException(status_code=400, detail=f"필드 {field} 설정 실패: {str(e)}")
    
    try:
        db.commit()
        db.refresh(issue)
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=f"데이터베이스 저장 실패: {str(e)}")
    
    return {
        "message": "관리 정보가 업데이트되었습니다.",
        "issue_id": issue.id,
        "updated_fields": list(update_data.keys())
    }

@router.post("/{issue_id}/completion-request")
async def request_completion(
    issue_id: int,
    request: schemas.CompletionRequestRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    완료 신청 - 담당자가 작업 완료 후 완료 신청
    """
    # 이슈 조회
    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="부적합을 찾을 수 없습니다.")
    
    # 진행 중 상태인지 확인
    if issue.review_status != ReviewStatus.in_progress:
        raise HTTPException(status_code=400, detail="진행 중 상태의 부적합만 완료 신청할 수 있습니다.")
    
    # 이미 완료 신청된 경우 확인
    if issue.completion_requested_at:
        raise HTTPException(status_code=400, detail="이미 완료 신청된 부적합입니다.")
    
    try:
        # 완료 사진 저장 (최대 5장)
        saved_paths = []
        for i in range(1, 6):
            photo_field = f"completion_photo{i if i > 1 else ''}"
            path_field = f"completion_photo_path{i if i > 1 else ''}"
            photo_data = getattr(request, photo_field, None)

            if photo_data:
                saved_path = save_base64_image(photo_data, "completion")
                if saved_path:
                    setattr(issue, path_field, saved_path)
                    saved_paths.append(saved_path)
                else:
                    raise Exception(f"{photo_field} 저장에 실패했습니다.")

        # 완료 신청 정보 업데이트
        issue.completion_requested_at = datetime.now()
        issue.completion_requested_by_id = current_user.id
        issue.completion_comment = request.completion_comment
        
        db.commit()
        db.refresh(issue)
        return {
            "message": "완료 신청이 성공적으로 제출되었습니다.",
            "issue_id": issue.id,
            "completion_requested_at": issue.completion_requested_at,
            "completion_photo_paths": saved_paths
        }

    except Exception as e:
        print(f"ERROR: 완료 신청 처리 오류 - {str(e)}")
        db.rollback()
        # 업로드된 파일이 있다면 삭제
        if 'saved_paths' in locals():
            for path in saved_paths:
                try:
                    delete_file(path)
                except:
                    pass
        raise HTTPException(status_code=500, detail=f"완료 신청 처리 중 오류가 발생했습니다: {str(e)}")

@router.post("/{issue_id}/reject-completion")
async def reject_completion_request(
    issue_id: int,
    request: schemas.CompletionRejectionRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    완료 신청 반려 - 관리자가 완료 신청을 반려
    """
    # 이슈 조회
    issue = db.query(Issue).filter(Issue.id == issue_id).first()
    if not issue:
        raise HTTPException(status_code=404, detail="부적합을 찾을 수 없습니다.")

    # 완료 신청이 있는지 확인
    if not issue.completion_requested_at:
        raise HTTPException(status_code=400, detail="완료 신청이 없는 부적합입니다.")

    # 권한 확인 (관리자 또는 관리함 접근 권한이 있는 사용자)
    if current_user.role != UserRole.admin and not check_page_access(current_user.id, 'issues_management', db):
        raise HTTPException(status_code=403, detail="완료 반려 권한이 없습니다.")

    try:
        # 완료 사진은 파일 삭제하지 않음 (재신청 시 참고용으로 보존)
        # DB 참조만 초기화

        # 완료 신청 정보 초기화
        issue.completion_requested_at = None
        issue.completion_requested_by_id = None
        for i in range(1, 6):
            path_field = f"completion_photo_path{i if i > 1 else ''}"
            setattr(issue, path_field, None)
        issue.completion_comment = None

        # 완료 반려 정보 기록 (전용 필드 사용)
        issue.completion_rejected_at = datetime.now()
        issue.completion_rejected_by_id = current_user.id
        issue.completion_rejection_reason = request.rejection_reason

        # 상태는 in_progress로 유지
        issue.review_status = ReviewStatus.in_progress

        db.commit()
        db.refresh(issue)
        return {
            "message": "완료 신청이 반려되었습니다.",
            "issue_id": issue.id,
            "rejection_reason": request.rejection_reason
        }

    except Exception as e:
        print(f"ERROR: 완료 반려 처리 오류 - {str(e)}")
        db.rollback()
        raise HTTPException(status_code=500, detail=f"완료 반려 처리 중 오류가 발생했습니다: {str(e)}")
