from typing import List
from fastapi import HTTPException
from sqlalchemy import func
from sqlalchemy.orm import Session
from app.api.display_board import schema
from app.dependency.authantication import JWTPayloadSchema
from app.locale.messages import Messages
from app.models.main.display_board import DisplayBoardBase, TblDisplayBoard
from app.models.main.store_formate import TblStoreFormat
from app.utils.schemas_utils import CustomResponse

class DisplayBoardService:
    def __init__(self, db: Session, token: JWTPayloadSchema):
        self.db = db
        self.token = token
        
    async def create_display_board(self, request: List[schema.DisplayBoardCreate]):
        created_display = []

        for item in request:

            # FIX: Multiple rows → use first(), not scalar()
            row = (
                self.db.query(TblStoreFormat.store_size)
                .filter(TblStoreFormat.group_id == item.group_id)
                .first()
            )

            if row is None:
                raise HTTPException(
                    status_code=400,
                    detail=f"store_size not found for group_id {item.group_id}"
                )

            store_size = row.store_size  # extract numeric value

            # total calculation
            if item.choice == "Unit Price":
                total = item.units * item.cost_per_unit

            elif item.choice == "Rate per SQFT":
                total = store_size * item.rate_per_sq

            else:
                raise HTTPException(
                    status_code=400,
                    detail=f"Unknown choice for item: {item.choice}"
                )

            request_data = item.model_dump()
            request_data["total"] = total

            created_display_board = DisplayBoardBase.model_validate(request_data)
            sale = TblDisplayBoard.create(created_display_board, self.db)
            created_display.append(sale)

        self.db.commit()

        return CustomResponse(status="1", message=Messages.DISPLAY_BOARD)

        
    # async def create_display_board(self, request: List[schema.DisplayBoardCreate]):
    #     created_display = []
    #     for item in request:
    #         store_size = (
    #             self.db.query(TblStoreFormat.store_size)
    #             .filter(TblStoreFormat.group_id == item.group_id)
    #             .first()
    #         )
    #         if store_size is None:
    #             raise HTTPException(
    #                 status_code=400,
    #                 detail=f"store_size not found for group_id {item.group_id}"
    #             )
    #         if item.choice == "Unit Price":
    #             total = item.units * item.cost_per_unit
    #         elif item.choice == "Rate per SQFT":
    #             total = store_size * item.rate_per_sq
    #         else:
    #             raise HTTPException(
    #                 status_code=400,
    #                 detail=f"Unknown feature_type or choice for item: {item}"
    #             )
    #         request_data = item.model_dump()
    #         request_data["total"] = total
    #         created_display_board = DisplayBoardBase.model_validate(request_data)
    #         sale = TblDisplayBoard.create(created_display_board, self.db)
    #         created_display.append(sale)
    #     self.db.commit()
    #     return CustomResponse(status="1", message=Messages.DISPLAY_BOARD)
    
    # async def create_display_board(self, request: schema.DisplayBoardCreate):
    #     total = request.size * request.cost_per_unit
    #     new=schema.DisplayBoardResopnce.model_validate(request)
    #     new.total=total
    #     creat_display= TblDisplayBoard.create(new, self.db)
    #     self.db.add(creat_display)
    #     self.db.commit()
    #     self.db.refresh(creat_display)
    #     return CustomResponse(status="1", message=Messages.DISPLAY_BOARD)
    
    
    async def get_display_board(self, group_id:int):
        new_get_display_board = TblDisplayBoard.get_by_display_board_data(group_id, self.db)
        if not new_get_display_board:
            raise HTTPException(status_code=404, detail="Get Display Board ID not found")
        return [schema.DisplayBoardResopnse.model_validate(get_group) for get_group in new_get_display_board]
    
    async def get_and_sum_display_board(self, group_id: int) ->"TblDisplayBoard":
        new_get_and_sum_display_board = (
            self.db.query(
                TblDisplayBoard.group_id, 
                TblDisplayBoard.store_format_type,
                func.sum(TblDisplayBoard.total).label("total_sum")
                )
                .filter(TblDisplayBoard.group_id == group_id)
                .group_by(TblDisplayBoard.group_id, TblDisplayBoard.store_format_type)
                .all()
        )
        if not new_get_and_sum_display_board:
            raise HTTPException(status_code=404, detail="Get sum ID not found")
        return [schema.DisplayBoardSum.model_validate(get_and_sum_display_board) for get_and_sum_display_board in new_get_and_sum_display_board]
    
    async def update_display_board(self, request: List[schema.DisplayBoardUpdate]):
        for req in request:
            total = req.size * req.cost_per_unit
            request_data = req.model_dump()
            request_data["total"] = total
            updated_display_board = DisplayBoardBase.model_validate(request_data)
            if updated_display_board.display_board_id is None:
                return CustomResponse(status="-1", message=Messages.DISPLAY_BOADR_UPDATE_NOT)
            TblDisplayBoard.update_display_board(updated_display_board.display_board_id,updated_display_board,self.db)
        self.db.commit()
        return CustomResponse(status="1", message=Messages.DISPLAY_BOADR_UPDATE_SUCCESSFULLY)
    
    async def delete_display_board(self, display_board_delete_id: int):
        deleted_display_board = TblDisplayBoard.delete_display_board(display_board_delete_id, self.db)
        if not deleted_display_board:
            return CustomResponse(status="-1", message=Messages.DISPLAY_BOADR_UPDATE_NOT)
        return CustomResponse(status="1", message=Messages.DISPLAY_BOARD_DELETE)