from fastapi import APIRouter, Depends, HTTPException, status, Body, Request, Query
from sqlalchemy.orm import Session
import logging
import os
from typing import Dict, Any, List, Optional
from app.common.database import get_db
from ..services.appointment_service import  get_paginated_appointments, fetch_call_log_by_twilio_id, send_appointment_email, create_appointment, send_appointment_email_update
from ..services.auth_service import verify_token_internally
from pydantic import BaseModel
from datetime import datetime, timezone
from fastapi.responses import JSONResponse
from typing import Dict, Any
from dateutil import parser
from datetime import datetime
from zoneinfo import ZoneInfo


logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
from app.common import schemas, models
from app.common.database import get_db


router = APIRouter()

class CatchPhraseCreate(BaseModel):
    phrases: str
    
    #  Helper function to format time
def format_time(time_str):
    return datetime.strptime(time_str, "%H:%M").strftime("%I:%M %p")

# Helper function to compare old and new timings
def compare_office_timings(old_timing: dict, new_timing: dict) -> list:
    messages = []
    all_days = set(old_timing.keys()) | set(new_timing.keys())  # union of all day keys

    for day in sorted(all_days):  # sorted for consistency
        old_day = old_timing.get(day)
        new_day = new_timing.get(day)

        # Day turned off
        if old_day and not new_day:
            messages.append(f"{day.capitalize()} has been turned off.")
            continue

        # Day turned on
        if not old_day and new_day:
            messages.append(f"{day.capitalize()} has been turned on.")
            continue

        # Both exist → check for changes
        if isinstance(old_day, dict) and isinstance(new_day, dict):
            old_start = old_day.get("start_time")
            old_end = old_day.get("end_time")
            new_start = new_day.get("start_time")
            new_end = new_day.get("end_time")

            if old_start != new_start or old_end != new_end:
                messages.append(
                    f"Updated Office Timing for {day.capitalize()} from "
                    f"{format_time(old_start)} - {format_time(old_end)} to "
                    f"{format_time(new_start)} - {format_time(new_end)}"
                )

    return messages



@router.get("/appointmentList", response_model=Dict[str, Any])
def read_appointment_list(
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=100),
    startDate: Optional[str] = Query(None),
    endDate: Optional[str] = Query(None),
    db: Session = Depends(get_db),
    current_user: Dict = Depends(verify_token_internally)
): 
    try:
        start = parser.isoparse(startDate).replace(tzinfo=None) if startDate else None
        end = parser.isoparse(endDate).replace(tzinfo=None) if endDate else None
    except ValueError as e:
        raise HTTPException(status_code=400, detail=f"Invalid datetime: {str(e)}")

    return get_paginated_appointments(db, page, page_size, start, end)


@router.get("/call-log/{twilio_call_id}", response_model=Dict[str, Any])
def get_call_log_by_twilio_id(
    twilio_call_id: str,
    db: Session = Depends(get_db),
    current_user: Dict = Depends(verify_token_internally)
):
    result = fetch_call_log_by_twilio_id(db, twilio_call_id)

    if not result:
        raise HTTPException(status_code=404, detail="Call log not found")

    return {"data": result}


@router.post("/appointment_scheduling", response_model=schemas.Appointment)
async def schedule_appointment(
    data: Dict[str, Any] = Body(...),
    # appointment: schemas.AppointmentCreate,
    db: Session = Depends(get_db),
):
    call_data = data.get("call", {})
    args = data.get("args", {})
    print(f"=-=-=-=-=-=-=-=Data 1: {data}, ============ arg {args}")
    # Get customer phone based on call direction
    direction = call_data.get("direction")
    if direction == "inbound":
        customer_phone = call_data.get("from_number")
    else:
        customer_phone = call_data.get("to_number")
    
    # print("==---------------------------------print telephony_identifier")
    # print(call_data.get("telephony_identifier"))
    # Get Twilio call SID and other identifiers
    twilio_call_sid = call_data.get("telephony_identifier", {}).get(
        "twilio_call_sid"
    )
    # print("==============================print telephony_identifier")
    # print(twilio_call_sid)
    
    local_time = datetime.strptime(args.get("schedule"), "%Y-%m-%d %H:%M:%S")
    local_time = local_time.replace(tzinfo=ZoneInfo("America/Los_Angeles"))
    utc_time = local_time.astimezone(ZoneInfo("UTC"))

    appointment_data = {
        "twilio_call_id":twilio_call_sid,
        "name": args.get("name"),
        "email": args.get("email"),
        "phone": customer_phone,
        "off_time": False if args.get("offTime") == 0 else True,
        "schedule": utc_time,
    }
    print(f"=-=-=-=-=-=-=-=Data 2: {appointment_data}")

    appointment_create = schemas.AppointmentCreate(**appointment_data)
    appointment_result, was_updated = create_appointment(db, appointment_create)
        
    appointment_data2 = {
        "name": args.get("name"),
        "email": args.get("email"),
        "phone": customer_phone,
        "schedule": args.get("schedule")
    }
    if was_updated:
        send_appointment_email_update(appointment_data2)
    else:
        send_appointment_email(appointment_data2)
    # # print(appointment)
    logger.info(f"Appointment: {appointment_data}")
    print(f"Appointment: {appointment_data}")
    # create_appointment(db, appointment)
    return JSONResponse(content={"message": "Appointment scheduled successfully."}, 
                        status_code=status.HTTP_200_OK)