from typing import Any from fastapi import APIRouter, Depends, HTTPException, Query from fastapi.responses import JSONResponse from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from db_setup import get_session from org_settings.views import Exclusion, OrgSetting from users.permissions import PermissionTag, require_permission router = APIRouter() class OrgSettingItem(BaseModel): key: str value: Any = None category: str class OrgSettingsUpdate(BaseModel): settings: list[OrgSettingItem] @router.get("/org-settings/fetch") async def fetch_org_settings( current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_VIEW)), category: str | None = Query(None), session: AsyncSession = Depends(get_session), ): try: service = OrgSetting(session=session) data, total = await service.get_settings(category) return JSONResponse(content={"data": data, "total": total, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.put("/org-settings/update") async def update_org_settings( payload: OrgSettingsUpdate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), session: AsyncSession = Depends(get_session), ): try: service = OrgSetting(session=session) data = await service.update_settings(payload.model_dump(exclude_unset=True), current_user) return JSONResponse(content={"data": data, "total": len(data), "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) class ExcludeUniversityCreate(BaseModel): name: str class ExcludeUniversityUpdate(BaseModel): name: str | None = None class ExcludeCompanyCreate(BaseModel): name: str linkedin_url: str | None = None class ExcludeCompanyUpdate(BaseModel): name: str | None = None linkedin_url: str | None = None class ExcludeUniversityBatchCreate(BaseModel): universities: list[ExcludeUniversityCreate] class ExcludeCompanyBatchCreate(BaseModel): companies: list[ExcludeCompanyCreate] @router.get("/org-settings/exclude-university/fetch") async def fetch_exclude_universities( current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_VIEW)), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data, total = await service.get_universities() return JSONResponse(content={"data": data, "total": total, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/org-settings/exclude-university/create") async def create_exclude_university( payload: ExcludeUniversityCreate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data = await service.create_university(payload.model_dump(exclude_unset=True), current_user) return JSONResponse(content={"data": data, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/org-settings/exclude-university/create-batch") async def create_exclude_universities_batch( payload: ExcludeUniversityBatchCreate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), session: AsyncSession = Depends(get_session), ): try: if not payload.universities: raise HTTPException(status_code=400, detail="universities is required") service = Exclusion(session=session) data = [] failed = [] for item in payload.universities: try: row = await service.create_university( item.model_dump(exclude_unset=True), current_user ) data.append(row) except HTTPException as e: failed.append({ "name": (item.name or "").strip(), "detail": e.detail if isinstance(e.detail, str) else str(e.detail), "status_code": e.status_code, }) return JSONResponse( content={"data": data, "total": len(data), "failed": failed, "status_code": 200} ) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.patch("/org-settings/exclude-university/update") async def update_exclude_university( payload: ExcludeUniversityUpdate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), record_id: str = Query(...), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data = await service.update_university( record_id, payload.model_dump(exclude_unset=True), current_user ) return JSONResponse(content={"data": data, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.delete("/org-settings/exclude-university/delete") async def delete_exclude_university( current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), record_id: str = Query(...), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data = await service.delete_university(record_id, current_user) return JSONResponse(content={"data": data, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/org-settings/exclude-company/fetch") async def fetch_exclude_companies( current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_VIEW)), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data, total = await service.get_companies() return JSONResponse(content={"data": data, "total": total, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/org-settings/exclude-company/create") async def create_exclude_company( payload: ExcludeCompanyCreate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data = await service.create_company(payload.model_dump(exclude_unset=True), current_user) return JSONResponse(content={"data": data, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/org-settings/exclude-company/create-batch") async def create_exclude_companies_batch( payload: ExcludeCompanyBatchCreate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), session: AsyncSession = Depends(get_session), ): try: if not payload.companies: raise HTTPException(status_code=400, detail="companies is required") service = Exclusion(session=session) data = [] failed = [] for item in payload.companies: try: row = await service.create_company( item.model_dump(exclude_unset=True), current_user ) data.append(row) except HTTPException as e: failed.append({ "name": (item.name or "").strip(), "detail": e.detail if isinstance(e.detail, str) else str(e.detail), "status_code": e.status_code, }) return JSONResponse( content={"data": data, "total": len(data), "failed": failed, "status_code": 200} ) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.patch("/org-settings/exclude-company/update") async def update_exclude_company( payload: ExcludeCompanyUpdate, current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), record_id: str = Query(...), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data = await service.update_company( record_id, payload.model_dump(exclude_unset=True), current_user ) return JSONResponse(content={"data": data, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.delete("/org-settings/exclude-company/delete") async def delete_exclude_company( current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_CONFIGURE)), record_id: str = Query(...), session: AsyncSession = Depends(get_session), ): try: service = Exclusion(session=session) data = await service.delete_company(record_id, current_user) return JSONResponse(content={"data": data, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e))