"""Repository for Insight Feedback database operations."""

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, desc
from typing import Optional, List
from uuid import UUID
from decimal import Decimal

from app.models.insight_feedback import InsightFeedback
from app.schemas.feedback import InsightFeedbackCreate


class FeedbackRepository:
    """Repository for Insight Feedback operations."""

    def __init__(self, session: AsyncSession):
        self.session = session

    async def create(self, feedback_data: InsightFeedbackCreate) -> InsightFeedback:
        """Create feedback for an insight."""
        # Calculate variance if both values provided
        variance = None
        if (feedback_data.expected_impact_value is not None and
                feedback_data.actual_impact_value is not None and
                feedback_data.expected_impact_value != 0):
            variance = (
                (feedback_data.actual_impact_value - feedback_data.expected_impact_value) /
                feedback_data.expected_impact_value * 100
            )

        feedback = InsightFeedback(
            **feedback_data.model_dump(exclude={'variance_percentage'}),
            variance_percentage=variance
        )
        self.session.add(feedback)
        await self.session.flush()
        await self.session.refresh(feedback)
        return feedback

    async def get_by_id(self, feedback_id: UUID) -> Optional[InsightFeedback]:
        """Get feedback by ID."""
        query = select(InsightFeedback).where(InsightFeedback.id == feedback_id)
        result = await self.session.execute(query)
        return result.scalar_one_or_none()

    async def get_by_insight(self, insight_id: UUID) -> List[InsightFeedback]:
        """Get all feedback for an insight."""
        query = select(InsightFeedback).where(
            InsightFeedback.insight_id == insight_id
        ).order_by(desc(InsightFeedback.created_at))

        result = await self.session.execute(query)
        return list(result.scalars().all())

    async def get_success_rate(self, insight_type: Optional[str] = None) -> float:
        """Calculate success rate for insights."""
        query = select(InsightFeedback)

        result = await self.session.execute(query)
        feedbacks = result.scalars().all()

        if not feedbacks:
            return 0.0

        successful = sum(1 for f in feedbacks if f.success)
        return (successful / len(feedbacks)) * 100

    async def get_average_impact_variance(self) -> Decimal:
        """Calculate average variance between expected and actual impact."""
        query = select(InsightFeedback).where(
            InsightFeedback.variance_percentage.isnot(None)
        )

        result = await self.session.execute(query)
        feedbacks = result.scalars().all()

        if not feedbacks:
            return Decimal('0.0')

        avg_variance = sum(f.variance_percentage for f in feedbacks) / len(feedbacks)
        return Decimal(str(round(float(avg_variance), 2)))
