from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session

from src.infrastructure.database.connection import get_db
from src.infrastructure.repositories.sql_product_repository import SqlProductRepository
from src.infrastructure.repositories.sql_merchant_offer_repository import SqlMerchantOfferRepository
from src.application.use_cases.get_merchant_products import GetMerchantProductsUseCase
from src.application.use_cases.get_merchant_offers import GetMerchantOffersUseCase
from src.application.use_cases.save_product import SaveProductUseCase
from src.application.use_cases.delete_product import DeleteProductUseCase
from src.application.use_cases.link_offers_to_product import LinkOffersToProductUseCase
from src.presentation.api.v1.products.schemas import (
    ProductResponse,
    ProductCreateRequest,
    ProductUpdateRequest,
    MerchantOfferResponse,
    LinkOffersRequest,
)
from src.core.exceptions import NotFoundError
from src.core.rbac.rbac_dependency import require_permission

router = APIRouter(tags=["Products"])


@router.get("/merchants/{merchant_id}/products", response_model=list[ProductResponse])
def get_products(
    merchant_id: int,
    db: Session = Depends(get_db),
    user=Depends(require_permission("products.view")),
):
    repo = SqlProductRepository(db)
    return GetMerchantProductsUseCase(repo).execute(merchant_id)


@router.get("/merchants/{merchant_id}/offers", response_model=list[MerchantOfferResponse])
def get_offers(
    merchant_id: int,
    db: Session = Depends(get_db),
    user=Depends(require_permission("products.view")),
):
    repo = SqlMerchantOfferRepository(db)
    return GetMerchantOffersUseCase(repo).execute(merchant_id)


@router.post("/merchants/{merchant_id}/products", response_model=ProductResponse, status_code=201)
def create_product(
    merchant_id: int,
    body: ProductCreateRequest,
    db: Session = Depends(get_db),
    user=Depends(require_permission("products.manage")),
):
    repo = SqlProductRepository(db)
    return SaveProductUseCase(repo).create(merchant_id, body.model_dump(), user.id)


@router.put("/merchants/{merchant_id}/products/{product_id}", response_model=ProductResponse)
def update_product(
    merchant_id: int,
    product_id: int,
    body: ProductUpdateRequest,
    db: Session = Depends(get_db),
    user=Depends(require_permission("products.manage")),
):
    repo = SqlProductRepository(db)
    try:
        return SaveProductUseCase(repo).update(product_id, body.model_dump(exclude_none=True))
    except NotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))


@router.delete("/merchants/{merchant_id}/products/{product_id}", status_code=204)
def delete_product(
    merchant_id: int,
    product_id: int,
    db: Session = Depends(get_db),
    user=Depends(require_permission("products.manage")),
):
    repo = SqlProductRepository(db)
    try:
        DeleteProductUseCase(repo).execute(product_id)
    except NotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))


@router.post("/products/{product_id}/link-offers", status_code=200)
def link_offers(
    product_id: int,
    body: LinkOffersRequest,
    db: Session = Depends(get_db),
    user=Depends(require_permission("products.manage")),
):
    repo = SqlMerchantOfferRepository(db)
    LinkOffersToProductUseCase(repo).execute(product_id, body.offer_ids, user.id)
    return {"message": "Offers linked successfully"}
