
    yi                         d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlmZ d dl	m
Z
 d dlmZmZmZ d dlmZ  ej"                  e      Z ed      Z G d	 d
      Z eej,                  ej.                  ej0                  ej2                  ej4                        ZdedefdZdededefdZdedefdZdeeef   defdZ dedededededede!deded efd!Z"d"Z#d# Z$y)$    N)ZoneInfo)datetime	timedelta)timezone)HTTPBasicAuth)DictAnyList)settingszAmerica/Los_Angelesc                       e Zd ZdZdZej                  Zdededededef
dZ	d	efd
Z
dededed	eeef   fdZdededededededededed	eeef   fdZy)XTimeClientz*
    Handles XTime API communication.
    z!https://auth.coxautoinc.com/token	client_idclient_secretapi_key	dealer_idscopesc                 X    || _         || _        || _        || _        || _        d | _        y )N)r   r   r   r   r   access_token)selfr   r   r   r   r   s         P/var/www/html/dp2/backend_v2.1/server/apps/appointments/services/xtime_client.py__init__zXTimeClient.__init__   s.    "*"     returnc           	         | j                   r| j                   S ddi}d| j                  d}	 t        j                  | j                  ||t        | j                  | j                        d      }|j                          |j                         }|d   | _         | j                   S # t        j                  $ r}t        j                  d|         d	}~ww xY w)
zP
        Fetch OAuth2 access token. Caches token in instance for reuse.
        Content-Typez!application/x-www-form-urlencodedclient_credentials)
grant_typescope   )headersdataauthtimeoutr   zFailed to fetch XTime token N)r   r   requestspost	TOKEN_URLr   r   r   raise_for_statusjsonRequestExceptionlogger	exception)r   r    r!   resp
token_dataexcs         r   get_access_tokenzXTimeClient.get_access_token   s     $$$!#FG2T[[I	=="4>>43E3EFD !!#J *> :D$$$(( 	;C5AB	s   A7B% %C8CCyearmakemodelc                    | j                    d| j                   }d| j                          | j                  dd}d|||di}	 t	        j
                  |||d      }|j                          |j                         S # t        j                  $ r/}t        j                  d	|        d
t        |      icY d}~S d}~ww xY w)z9
        Fetch available services for a vehicle.
        z/services/dealer/Bearer zapplication/json)Authorization	x-api-keyr   vehicler0   r1   r2   r   r    r(   r#   zFailed to fetch services: errorNAPI_BASE_URLr   r/   r   r$   r%   r'   r(   r)   r*   warningstr)	r   r0   r1   r2   urlr    payloadr,   r.   s	            r   get_services_for_vehiclez$XTimeClient.get_services_for_vehicle9   s     ""##4T^^4DE&t'<'<'>&?@.

 tTEJK	'==gGRPD!!#99;(( 	'NN7u=>SX&&	's   8A? ?C$B<6C<Cappointment_datetime
first_name	last_nameemailphoneopcodec
           	         | j                    d| j                   }
d| j                          | j                  | j                  d}||||||||dd|	igd}	 t	        j
                  |
||d      }|j                          |j                         S # t        j                  $ r4}t        j                  d	|        d
t        |      d| dcY d}~S d}~ww xY w)z/
        Book an appointment in XTime.
        z/appointments-bookings/dealer/r4   )r5   r6   
dealerCoder8   rG   )appointmentDateTimeLocal	firstNamelastNameemailAddressphoneNumberr7   servicesr   r9   z"Failed to book XTime appointment: FzUnable to get Services )successmessager:   Nr;   )r   rB   rC   rD   rE   rF   r0   r1   r2   rG   r?   r    r@   r,   r.   s                  r   book_appointmentzXTimeClient.book_appointmentM   s     ""##A$..AQR&t'<'<'>&?@..
 )=#!!  $dUC"F+,

	==gGRPD!!#99;(( 	NN?uEF s823%8 	s   8B C%)CCCN)__name__
__module____qualname____doc__r&   r   COXAUTO_API_BASE_URLr<   r>   r   r/   intr   r	   rA   rR    r   r   r   r      s     4I00L!# !c !C !TW !ad !# 4'S ' 'C 'DQTVYQYN '()"%) ) 	)
 ) ) ) ) ) ) 
c3h)r   r   )r   r   r   r   r   dtr   c                     t        j                  | d      }|t        d      z   }|j                  d       d|j                  d       S )zj
    Convert "2024-06-14 10:30:00" -> "2024-06-14T10:30-10:45"
    Adds 15 minutes to the start time.
    z%Y-%m-%d %H:%M:%S   )minutes%Y-%m-%dT%H:%M-%H:%M)r   strptimer   strftime)rZ   start_dtend_dts      r   x_time_native_dtre      sR       %89H 	"--F  012!FOOG4L3MNNr   rc   rd   c                     t        j                  |       st        j                  |      rt        d      | j                  d       d|j                  d       S )z
    Convert:
      start_dt = 2024-06-14 10:30:00-07:00
      end_dt   = 2024-06-14 10:45:00-07:00

    -> "2024-06-14T10:30-10:45"

    Expects timezone-aware datetime objects.
    z5start_dt and end_dt must be timezone-aware date timesr^   r_   r`   )r   is_naive
ValueErrorrb   )rc   rd   s     r   x_time_native_rangeri      sZ     "h&7&7&?PQQ -.
/
FOOG$%	'r   textc                     | j                         } t        j                  dd|       } t        j                  dd|       j                         } | S )z8
    Normalize service names for reliable matching.
    z[^a-z0-9\s] z\s+ )lowerresubstrip)rj   s    r   	normalizerr      sA     ::<D66."d+D66&#t$**,DKr   xtime_services_responsebooking_typec                    | j                  dg       }|syt        |      }d}d}d}|D ]  }|j                  dd      }t        |      }	t        |j                               }
t        |	j                               }|
j	                  |      }t        |      }||	v r|dz  }||kD  s}|}|j                  d      }|j                  d      } ||fS )z
    Given XTime services API response and a local booking type string
    (e.g. "oil change"), return the best matching opcode.

    Uses scoring instead of naive contains() for better reliability.
    rO   Nr   serviceNamerl      rG   )getrr   setsplitintersectionlen)rs   rt   rO   booking_norm
best_scorebest_opcode	best_nameserviceservice_nameservice_normbooking_wordsservice_wordscommon_wordsscores                 r   find_best_service_opcoder      s     &=%@%@R%PH\*LJKI{{="5 . L..01L..01 %11-@L! <'QJE:J!++h/KM2I' * 	!!r   appointment_start_dtappointment_end_dtrC   rD   rE   rF   r0   r1   r2   r   c
                    t         j                          t         j                  |||      }
t        | |      }|
j	                  d      r|
|d |	fS t        |
|	      \  }}	t         j                  |||||||||	      |||	fS )Nr8   r:   )	rB   rC   rD   rE   rF   r0   r1   r2   rG   )xtime_clientr/   rA   ri   rx   r   rR   )r   r   rC   rD   rE   rF   r0   r1   r2   r   services_responserZ   rG   s                r   book_appointment_x_timer      s     !!#$== >  

B
 W% "dL883FL
 (( ) 
 
6<
  
 r   z@
from apps.appointments.services import full_test2
full_test2()
c                  x    t        t        dddddt              t        dddddt              dd	d
ddddd
      S )Ni        
   r   )tzinfo-   shamashaqzshamas.haq@flutenai.com
1234323243i  NissanArmadaz
oil change)
r   r   rC   rD   rE   rF   r0   r1   r2   r   )r   r   PACIFICrY   r   r   
full_test2r     s_    "%
 $
 '!1 r   )%ro   loggingr$   zoneinfor   r   r   django.utilsr   requests.authr   typingr   r	   r
   django.confr   	getLoggerrS   r*   r   r   XTIME_CLIENT_IDXTIME_CLIENT_SECRETXTIME_API_KEYXTIME_DEALER_IDXTIME_SCOPESr   r>   re   ri   rr   r   rX   r   nr   rY   r   r   <module>r      sY   	    ( ! ' " "  			8	$
(
)g gR &&..""&&  O O O( H  (C C *"!#s(^*"*"Z* &* $*  *  	* 
 *  *  *  *  *  * X
r   