from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from datetime import datetime
from typing import List
from ..database import get_db
from ..models import User, DealerApplication, DealerInfo
from ..models.dealer import generate_dealer_code
from ..schemas import (
    DealerApplicationCreate, DealerApplicationResponse,
    DealerApplicationReject, DealerInfoResponse, DealerPublicInfo,
)
from .auth import get_current_user
from .notification import notify_dealer_approved, notify_dealer_rejected

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


@router.post("/apply", response_model=DealerApplicationResponse)
def apply_dealer(
    application: DealerApplicationCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Submit a dealer application"""
    # Check if user already has a pending or approved application
    existing = db.query(DealerApplication).filter(
        DealerApplication.user_id == current_user.id,
        DealerApplication.status.in_(["pending", "approved"])
    ).first()

    if existing:
        if existing.status == "approved":
            raise HTTPException(status_code=400, detail="You are already a dealer")
        raise HTTPException(status_code=400, detail="You already have a pending application")

    # Check if user is already a dealer
    if current_user.is_dealer:
        raise HTTPException(status_code=400, detail="You are already a dealer")

    # Create new application
    new_application = DealerApplication(
        user_id=current_user.id,
        business_name=application.business_name,
        business_number=application.business_number,
        real_name=application.real_name,
        id_number_encrypted=application.id_number,  # TODO: Encrypt this properly
        phone=application.phone,
        bank_name=application.bank_name,
        bank_account=application.bank_account,
        account_holder=application.account_holder,
        photo_url=application.photo_url,
        status="pending"
    )

    db.add(new_application)
    db.commit()
    db.refresh(new_application)
    return new_application


@router.get("/my-application", response_model=DealerApplicationResponse)
def get_my_application(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get current user's dealer application"""
    application = db.query(DealerApplication).filter(
        DealerApplication.user_id == current_user.id
    ).order_by(DealerApplication.applied_at.desc()).first()

    if not application:
        raise HTTPException(status_code=404, detail="No application found")

    return application


@router.get("/my-info", response_model=DealerInfoResponse)
def get_my_dealer_info(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Get current user's dealer info (if approved)"""
    if not current_user.is_dealer:
        raise HTTPException(status_code=403, detail="You are not a dealer")

    dealer_info = db.query(DealerInfo).filter(
        DealerInfo.user_id == current_user.id
    ).first()

    if not dealer_info:
        raise HTTPException(status_code=404, detail="Dealer info not found")

    return dealer_info


@router.get("/list", response_model=List[DealerPublicInfo])
def list_dealers(
    db: Session = Depends(get_db)
):
    """Get list of active dealers (public info only)"""
    dealers = db.query(DealerInfo).filter(
        DealerInfo.is_active == True
    ).all()
    return dealers


# Admin endpoints
@router.get("/admin/applications", response_model=List[DealerApplicationResponse])
def get_applications(
    status_filter: str = None,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """[Admin] Get all dealer applications"""
    if not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Admin access required")

    query = db.query(DealerApplication)
    if status_filter:
        query = query.filter(DealerApplication.status == status_filter)

    applications = query.order_by(DealerApplication.applied_at.desc()).all()
    return applications


@router.put("/admin/applications/{application_id}/approve", response_model=DealerInfoResponse)
def approve_application(
    application_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """[Admin] Approve a dealer application"""
    if not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Admin access required")

    application = db.query(DealerApplication).filter(
        DealerApplication.id == application_id
    ).first()

    if not application:
        raise HTTPException(status_code=404, detail="Application not found")

    if application.status != "pending":
        raise HTTPException(status_code=400, detail="Application is not pending")

    # Generate unique dealer code
    dealer_code = generate_dealer_code()
    while db.query(DealerInfo).filter(DealerInfo.dealer_code == dealer_code).first():
        dealer_code = generate_dealer_code()

    # Create dealer info
    dealer_info = DealerInfo(
        user_id=application.user_id,
        dealer_code=dealer_code,
        business_name=application.business_name,
        real_name=application.real_name,
        phone=application.phone,
        photo_url=application.photo_url,
        bank_name=application.bank_name,
        bank_account=application.bank_account,
        account_holder=application.account_holder,
    )

    # Update application status
    application.status = "approved"
    application.approved_at = datetime.utcnow()

    # Update user is_dealer flag
    user = db.query(User).filter(User.id == application.user_id).first()
    user.is_dealer = True

    db.add(dealer_info)
    db.commit()
    db.refresh(dealer_info)

    # TODO: Generate dealer card image here
    # dealer_info.dealer_card_url = generate_dealer_card(dealer_info)
    # db.commit()

    # Send notification to user about dealer approval
    notify_dealer_approved(db, application.user_id, dealer_code)

    return dealer_info


@router.put("/admin/applications/{application_id}/reject")
def reject_application(
    application_id: int,
    reject_data: DealerApplicationReject,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """[Admin] Reject a dealer application"""
    if not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Admin access required")

    application = db.query(DealerApplication).filter(
        DealerApplication.id == application_id
    ).first()

    if not application:
        raise HTTPException(status_code=404, detail="Application not found")

    if application.status != "pending":
        raise HTTPException(status_code=400, detail="Application is not pending")

    application.status = "rejected"
    application.rejected_reason = reject_data.reason

    db.commit()

    # Send notification to user about dealer rejection
    notify_dealer_rejected(db, application.user_id, reject_data.reason)

    return {"message": "Application rejected", "reason": reject_data.reason}


@router.get("/admin/dealers", response_model=List[DealerInfoResponse])
def get_all_dealers(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """[Admin] Get all dealers with full info"""
    if not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Admin access required")

    dealers = db.query(DealerInfo).all()
    return dealers


@router.put("/admin/dealers/{dealer_id}/toggle-active")
def toggle_dealer_active(
    dealer_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """[Admin] Toggle dealer active status"""
    if not current_user.is_admin:
        raise HTTPException(status_code=403, detail="Admin access required")

    dealer = db.query(DealerInfo).filter(DealerInfo.id == dealer_id).first()
    if not dealer:
        raise HTTPException(status_code=404, detail="Dealer not found")

    dealer.is_active = not dealer.is_active

    # Also update user's is_dealer status
    user = db.query(User).filter(User.id == dealer.user_id).first()
    if user:
        user.is_dealer = dealer.is_active

    db.commit()

    return {"message": f"Dealer {'activated' if dealer.is_active else 'deactivated'}", "is_active": dealer.is_active}
