from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from app.models import get_db
from app.models.dit import DitRecord
from app.models.sample import SampleRecord
from app.models.order import OrderRecord
from app.models.match import MatchResult, MatchStatus, TargetType
from app.services.fuzzy_matcher import FuzzyMatcher

router = APIRouter(prefix="/match", tags=["Matching"])

class MatchRunResponse(BaseModel):
    match_count: int
    auto_matched: int
    pending_review: int

class DitInfo(BaseModel):
    id: int
    op_id: str
    customer: str
    pn: str
    eau: int
    stage: Optional[str]

    class Config:
        from_attributes = True

class TargetInfo(BaseModel):
    id: int
    sample_id: Optional[str] = None
    customer: str
    pn: str
    order_no: Optional[str]
    qty: Optional[int]

class MatchResultResponse(BaseModel):
    id: int
    dit_id: int
    target_type: str
    target_id: int
    score: float
    reason: str
    status: str
    dit: Optional[DitInfo]
    target: Optional[TargetInfo]

    class Config:
        from_attributes = True

class ReviewRequest(BaseModel):
    action: str  # 'accept' or 'reject'

@router.post("/run", response_model=MatchRunResponse)
def run_matching(db: Session = Depends(get_db)):
    """執行模糊比對"""
    matcher = FuzzyMatcher(db)
    result = matcher.run_matching()
    return MatchRunResponse(**result)

@router.get("/results", response_model=List[MatchResultResponse])
def get_results(db: Session = Depends(get_db)):
    """取得所有比對結果"""
    matches = db.query(MatchResult).all()

    results = []
    for match in matches:
        # 取得 DIT 資訊
        dit = db.query(DitRecord).filter(DitRecord.id == match.dit_id).first()
        dit_info = DitInfo(
            id=dit.id,
            op_id=dit.op_id,
            customer=dit.customer,
            pn=dit.pn,
            eau=dit.eau,
            stage=dit.stage
        ) if dit else None

        # 取得目標資訊
        target_info = None
        if match.target_type == TargetType.SAMPLE:
            sample = db.query(SampleRecord).filter(SampleRecord.id == match.target_id).first()
            if sample:
                target_info = TargetInfo(
                    id=sample.id,
                    sample_id=sample.sample_id,
                    customer=sample.customer,
                    pn=sample.pn,
                    order_no=sample.order_no,
                    qty=sample.qty
                )
        elif match.target_type == TargetType.ORDER:
            order = db.query(OrderRecord).filter(OrderRecord.id == match.target_id).first()
            if order:
                target_info = TargetInfo(
                    id=order.id,
                    sample_id=order.order_id,
                    customer=order.customer,
                    pn=order.pn,
                    order_no=order.order_no,
                    qty=order.qty
                )

        results.append(MatchResultResponse(
            id=match.id,
            dit_id=match.dit_id,
            target_type=match.target_type.value,
            target_id=match.target_id,
            score=match.score,
            reason=match.reason,
            status=match.status.value,
            dit=dit_info,
            target=target_info
        ))

    return results

@router.put("/{match_id}/review", response_model=MatchResultResponse)
def review_match(match_id: int, request: ReviewRequest, db: Session = Depends(get_db)):
    """審核比對結果"""
    if request.action not in ['accept', 'reject']:
        raise HTTPException(status_code=400, detail="Invalid action")

    matcher = FuzzyMatcher(db)
    match = matcher.review_match(match_id, request.action)

    if not match:
        raise HTTPException(status_code=404, detail="Match not found")

    # 取得相關資訊
    dit = db.query(DitRecord).filter(DitRecord.id == match.dit_id).first()
    dit_info = DitInfo(
        id=dit.id,
        op_id=dit.op_id,
        customer=dit.customer,
        pn=dit.pn,
        eau=dit.eau,
        stage=dit.stage
    ) if dit else None

    target_info = None
    if match.target_type == TargetType.SAMPLE:
        sample = db.query(SampleRecord).filter(SampleRecord.id == match.target_id).first()
        if sample:
            target_info = TargetInfo(
                id=sample.id,
                sample_id=sample.sample_id,
                customer=sample.customer,
                pn=sample.pn,
                order_no=sample.order_no,
                qty=sample.qty
            )
    elif match.target_type == TargetType.ORDER:
        order = db.query(OrderRecord).filter(OrderRecord.id == match.target_id).first()
        if order:
            target_info = TargetInfo(
                id=order.id,
                sample_id=order.order_id,
                customer=order.customer,
                pn=order.pn,
                order_no=order.order_no,
                qty=order.qty
            )

    return MatchResultResponse(
        id=match.id,
        dit_id=match.dit_id,
        target_type=match.target_type.value,
        target_id=match.target_id,
        score=match.score,
        reason=match.reason,
        status=match.status.value,
        dit=dit_info,
        target=target_info
    )
