from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy import func as sql_func
from pydantic import BaseModel
from datetime import date, datetime
from typing import Optional
from app.database import get_db
from app.models.farmer_support import PlantIssueReport, PlantWarrantyClaim, FarmerSupportTicket
from app.models.farmer import FarmerProfile
from app.models.passport import PlantPassport
from app.services.auth import get_current_user

router = APIRouter(prefix="/plant-support", tags=["plant-support"])


def _generate_issue_code(db: Session) -> str:
    year = date.today().year
    last = db.query(PlantIssueReport).order_by(PlantIssueReport.created_at.desc()).first()
    if last:
        try:
            seq = int(last.issue_number.split("-")[-1]) + 1
        except (ValueError, IndexError):
            seq = db.query(PlantIssueReport).count() + 1
    else:
        seq = db.query(PlantIssueReport).count() + 1
    return f"ISS-{year}-{seq:06d}"


def _generate_warranty_code(db: Session) -> str:
    year = date.today().year
    last = db.query(PlantWarrantyClaim).order_by(PlantWarrantyClaim.created_at.desc()).first()
    if last:
        try:
            seq = int(last.claim_number.split("-")[-1]) + 1
        except (ValueError, IndexError):
            seq = db.query(PlantWarrantyClaim).count() + 1
    else:
        seq = db.query(PlantWarrantyClaim).count() + 1
    return f"WAR-{year}-{seq:06d}"


def _generate_ticket_code(db: Session) -> str:
    year = date.today().year
    last = db.query(FarmerSupportTicket).order_by(FarmerSupportTicket.created_at.desc()).first()
    if last:
        try:
            seq = int(last.ticket_number.split("-")[-1]) + 1
        except (ValueError, IndexError):
            seq = db.query(FarmerSupportTicket).count() + 1
    else:
        seq = db.query(FarmerSupportTicket).count() + 1
    return f"TIC-{year}-{seq:06d}"


# --- Issue Reports ---
class IssueReportCreate(BaseModel):
    activation_id: str
    issue_type: str
    title: str
    description: Optional[str] = None
    severity: str = "low"
    photo_url: Optional[str] = None
    video_url: Optional[str] = None


class IssueReportOut(BaseModel):
    id: str
    issue_number: str
    activation_id: str
    issue_type: str
    title: str
    description: Optional[str]
    severity: str
    photo_url: Optional[str]
    video_url: Optional[str]
    status: str
    assigned_to: Optional[str]
    resolution: Optional[str]
    resolved_at: Optional[datetime]
    created_at: Optional[datetime]

    model_config = {"from_attributes": True}


@router.get("/issues", response_model=list[IssueReportOut])
def list_issues(farmer_id: Optional[str] = None, activation_id: Optional[str] = None, db: Session = Depends(get_db)):
    q = db.query(PlantIssueReport)
    if activation_id:
        q = q.filter(PlantIssueReport.activation_id == activation_id)
    if farmer_id:
        q = q.join(PlantIssueReport.activation).filter(PlantIssueReport.activation.has(farmer_id=farmer_id))
    return q.order_by(PlantIssueReport.created_at.desc()).all()


@router.post("/issues", response_model=IssueReportOut)
def create_issue(data: IssueReportCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    from app.models.plant_activation import PlantActivation
    activation = db.query(PlantActivation).filter(PlantActivation.id == data.activation_id).first()
    if not activation:
        raise HTTPException(404, "Activation not found")

    issue = PlantIssueReport(
        issue_number=_generate_issue_code(db),
        activation_id=data.activation_id,
        issue_type=data.issue_type,
        title=data.title,
        description=data.description,
        severity=data.severity,
        photo_url=data.photo_url,
        video_url=data.video_url,
        status="open",
        recorded_by=user.id if hasattr(user, 'id') else None,
    )
    db.add(issue)
    db.commit()
    db.refresh(issue)
    return issue


@router.post("/issues/{issue_id}/resolve", response_model=IssueReportOut)
def resolve_issue(issue_id: str, resolution: Optional[str] = None, db: Session = Depends(get_db), user=Depends(get_current_user)):
    issue = db.query(PlantIssueReport).filter(PlantIssueReport.id == issue_id).first()
    if not issue:
        raise HTTPException(404, "Issue not found")
    issue.status = "resolved"
    issue.resolution = resolution
    issue.resolved_at = datetime.now()
    db.commit()
    db.refresh(issue)
    return issue


# --- Warranty Claims ---
class WarrantyClaimCreate(BaseModel):
    activation_id: str
    claim_type: str
    reason: Optional[str] = None
    photo_url: Optional[str] = None


class WarrantyClaimOut(BaseModel):
    id: str
    claim_number: str
    activation_id: str
    warranty_start: Optional[date]
    warranty_end: Optional[date]
    claim_date: Optional[date]
    claim_type: str
    reason: Optional[str]
    photo_url: Optional[str]
    status: str
    nursery_response: Optional[str]
    resolved_by: Optional[str]
    resolved_at: Optional[datetime]
    created_at: Optional[datetime]

    model_config = {"from_attributes": True}


@router.get("/warranty", response_model=list[WarrantyClaimOut])
def list_warranty(farmer_id: Optional[str] = None, activation_id: Optional[str] = None, db: Session = Depends(get_db)):
    q = db.query(PlantWarrantyClaim)
    if activation_id:
        q = q.filter(PlantWarrantyClaim.activation_id == activation_id)
    if farmer_id:
        q = q.join(PlantWarrantyClaim.activation).filter(PlantWarrantyClaim.activation.has(farmer_id=farmer_id))
    return q.order_by(PlantWarrantyClaim.created_at.desc()).all()


@router.post("/warranty", response_model=WarrantyClaimOut)
def create_warranty(data: WarrantyClaimCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    from app.models.plant_activation import PlantActivation
    activation = db.query(PlantActivation).filter(PlantActivation.id == data.activation_id).first()
    if not activation:
        raise HTTPException(404, "Activation not found")

    warranty = PlantWarrantyClaim(
        claim_number=_generate_warranty_code(db),
        activation_id=data.activation_id,
        claim_type=data.claim_type,
        reason=data.reason,
        photo_url=data.photo_url,
        status="pending",
    )
    db.add(warranty)
    db.commit()
    db.refresh(warranty)
    return warranty


@router.post("/warranty/{claim_id}/respond", response_model=WarrantyClaimOut)
def respond_warranty(claim_id: str, response_text: str = "", db: Session = Depends(get_db), user=Depends(get_current_user)):
    claim = db.query(PlantWarrantyClaim).filter(PlantWarrantyClaim.id == claim_id).first()
    if not claim:
        raise HTTPException(404, "Warranty claim not found")
    claim.nursery_response = response_text
    claim.status = "responded"
    db.commit()
    db.refresh(claim)
    return claim


@router.post("/warranty/{claim_id}/resolve", response_model=WarrantyClaimOut)
def resolve_warranty(claim_id: str, db: Session = Depends(get_db), user=Depends(get_current_user)):
    claim = db.query(PlantWarrantyClaim).filter(PlantWarrantyClaim.id == claim_id).first()
    if not claim:
        raise HTTPException(404, "Warranty claim not found")
    claim.status = "resolved"
    claim.resolved_at = datetime.now()
    claim.resolved_by = user.id if hasattr(user, 'id') else None
    db.commit()
    db.refresh(claim)
    return claim


# --- Support Tickets ---
class SupportTicketCreate(BaseModel):
    farmer_id: str
    activation_id: Optional[str] = None
    category: str
    priority: str = "medium"
    subject: str
    message: Optional[str] = None
    photo_url: Optional[str] = None


class SupportTicketOut(BaseModel):
    id: str
    ticket_number: str
    farmer_id: str
    activation_id: Optional[str]
    category: str
    priority: str
    subject: str
    message: Optional[str]
    photo_url: Optional[str]
    status: str
    assigned_to: Optional[str]
    response: Optional[str]
    resolved_at: Optional[datetime]
    created_at: Optional[datetime]

    model_config = {"from_attributes": True}


@router.get("/tickets", response_model=list[SupportTicketOut])
def list_tickets(farmer_id: Optional[str] = None, activation_id: Optional[str] = None, db: Session = Depends(get_db)):
    q = db.query(FarmerSupportTicket)
    if farmer_id:
        q = q.filter(FarmerSupportTicket.farmer_id == farmer_id)
    if activation_id:
        q = q.filter(FarmerSupportTicket.activation_id == activation_id)
    return q.order_by(FarmerSupportTicket.created_at.desc()).all()


@router.post("/tickets", response_model=SupportTicketOut)
def create_ticket(data: SupportTicketCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    farmer = db.query(FarmerProfile).filter(FarmerProfile.id == data.farmer_id).first()
    if not farmer:
        raise HTTPException(404, "Farmer profile not found")

    ticket = FarmerSupportTicket(
        ticket_number=_generate_ticket_code(db),
        farmer_id=data.farmer_id,
        activation_id=data.activation_id,
        category=data.category,
        priority=data.priority,
        subject=data.subject,
        message=data.message,
        photo_url=data.photo_url,
        status="open",
    )
    db.add(ticket)
    db.commit()
    db.refresh(ticket)
    return ticket


@router.post("/tickets/{ticket_id}/respond", response_model=SupportTicketOut)
def respond_ticket(ticket_id: str, response_text: str = "", db: Session = Depends(get_db), user=Depends(get_current_user)):
    ticket = db.query(FarmerSupportTicket).filter(FarmerSupportTicket.id == ticket_id).first()
    if not ticket:
        raise HTTPException(404, "Ticket not found")
    ticket.response = response_text
    ticket.status = "in_progress"
    db.commit()
    db.refresh(ticket)
    return ticket


@router.post("/tickets/{ticket_id}/resolve", response_model=SupportTicketOut)
def resolve_ticket(ticket_id: str, db: Session = Depends(get_db), user=Depends(get_current_user)):
    ticket = db.query(FarmerSupportTicket).filter(FarmerSupportTicket.id == ticket_id).first()
    if not ticket:
        raise HTTPException(404, "Ticket not found")
    ticket.status = "resolved"
    ticket.resolved_at = datetime.now()
    db.commit()
    db.refresh(ticket)
    return ticket
