o
    h=                     @   s  d Z ddlZddlmZ ddlmZ ddlmZmZ ddlm	Z	m
Z
mZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ddl'm(Z(m)Z)m*Z* e+e,Z-e	ddgdZ.i Z/i Z0dade1de2de3fddZ4dade1de5de2fddZ6e.j7de
egde
efdefddZ8e.j7de
egde
efde1defd d!Z9e.j:d"e
egde
efdefd#d$Z;dd%lm<Z<m=Z= e.j>d&e
egde
efde1d'e2d(e<e1e=f defd)d*Z?e.j:d+ed,e
efd-e$dedefd.d/Z@e.j:d0e!d,e
efd-e#dede!fd1d2ZAe.j:d3ed,e
ee
efd4ededefd5d6ZBe.j7d7e%d,e
efd4ede%fd8d9ZCe.j>d7e%d,e
ee
efd-e&d4edede%fd:d;ZDe.j:d<ed,e
ee
efd=e d4ededefd>d?ZEe.j7d@e"d,ddAe
ee
efdBe2dCe2dDedede"f
dEdFZFe.j7dGe%d,e
ee
efdHe2dDedede%fdIdJZGe.j:d@e%d,e
ee
efd-edDedede%fdKdLZHe.j>dGe%d,e
ee
efdHe2d-edDedede%f
dMdNZIe.jJdGed,e
ee
efdHe2dDededefdOdPZKe.j7dQed,defdRdSZLe.j:dTe!d,e
efdUedede!fdVdWZMe.j7dTe!d,edXdYdZe
efd[e1dede!fd\d]ZNe.j:d^e!d,e
efdUedede!fd_d`ZOdS )bzu
Authentication and user management API endpoints.
Handles registration, login, logout, and user profile management.
    N)List)	lru_cache)datetime	timedelta)	APIRouterDependsHTTPExceptionstatusQuery)Session)settings)get_db)get_current_admin_userget_current_user)User)AdminUserCreateAdminUserUpdateGoogleAuthRequestGoogleAuthCodeRequestGoogleOAuthUrlResponseMessageResponsePasswordChangeTokenResponseUserListResponse	UserLoginUserRegisterUserResponse
UserUpdate)AuthServiceUserServiceGoogleAuthServicez	/api/authauthentication)prefixtags	cache_keymax_age_minutesreturnc                 C   s*   |du rt j}| tvrdS t t|  k S )z$Check if cache entry is still valid.NF)r   CACHE_TTL_MINUTES_cache_expiryr   now)r$   r%    r*   -/var/www/html/aiguide_backend/routers/auth.py_is_cache_valid"   s
   r,   datac                 C   s0   |du rt j}|t| < t t|d t| < dS )zSet cache entry with expiry.N)minutes)r   r'   _admin_cacher   r)   r   r(   )r$   r-   r%   r*   r*   r+   
_set_cache+   s   r0   z/admin/tables)dependenciesdbc                    s`   d}t |ddrt| S ddlm} || j}| }dd |D }d|i}t||dd |S )	z6Get list of available database tables for admin panel.available_tables
   )r%   r   inspectc                 S   s   g | ]}|d v r|qS )userspaymentslayerslayer_translationspoispoi_translationsr*   ).0tabler*   r*   r+   
<listcomp>A       z(get_available_tables.<locals>.<listcomp>tables)r,   r/   
sqlalchemyr6   bindget_table_namesr0   )r2   r$   r6   	inspectorrB   
app_tablesresultr*   r*   r+   get_available_tables4   s   
rI   z/admin/table/{table_name}
table_namec              
      s6  ddl m} g d}| |vrtdddznddl m} ||j}|| }dd	 |D }||d
|  d}| }	g }
|	D ]9}t|drP|
	t
|j q@t|dr]|
	|  q@i }t|D ]\}}|t|k rs|| ||< qc|
	| q@| ||
t|
dW S  ty } ztddt| dd}~ww )zGet data from specific table.r   textr7     Table not allowedstatus_codedetailr5   c                 S      g | ]}|d  qS namer*   r>   colr*   r*   r+   r@   X       z"get_table_data.<locals>.<listcomp>zSELECT * FROM z
 LIMIT 100_mapping_asdict)rJ   columnsr-   
total_rows  zError fetching table data: N)rC   rL   r   r6   rD   get_columnsexecutefetchallhasattrappenddictrX   rY   	enumeratelen	Exceptionstr)rJ   r2   rL   allowed_tablesr6   rF   table_columnsrZ   rH   rowsr-   rowrow_dicticol_nameer*   r*   r+   get_table_dataI   sB   



ro   z/admin/refresh-tablesc              
      s<   zddiW S  t y } ztddt| dd}~ww )z"Refresh table structures and data.messagezTables refreshed successfullyr\   zError refreshing tables: rO   N)re   r   rf   )r2   rn   r*   r*   r+   refresh_tablesx   s   
rq   )DictAnyz%/admin/table/{table_name}/{record_id}	record_idupdate_datac                    s  ddl m} td|  d|  td|  tddd | D   g d	}| |vr7td
ddzddl m} ||j}|| }dd |D }	i }
g }| D ]\}}|dkr`qW||	vrj|	| qW||
|< qW|rtd
dd
| dd
dd |	D  d|
std
ddg }d|i}|
 D ]\}}|	| d|  |||< qd|  dd
| d}||||}|  |jdkrtddddt|
 dW S  ty     ty } z|  t|}d|v r%d|v r%d |v rtd!d"d#d$d%d&dd'|v rtd!d"d(d)d%d&dtd!d"d*d%d+dd,| v s3d-| v r=td!d"d.d/d+dd0| v sKd1| v rUtd!d"d2d3d+dd4| v scd5| v rmtd!d"d6d7d+dtd8|  d| d9|  td:d;dd<}~ww )=z$Update a specific record in a table.r   rK   u   📨 Update request for z record u   📋 Update data: u   📊 Data types: c                 S   s   g | ]\}}|t |jfqS r*   )type__name__)r>   kvr*   r*   r+   r@      s    z'update_table_record.<locals>.<listcomp>r7   rM   rN   rO   r5   c                 S   rR   rS   r*   rU   r*   r*   r+   r@      rW   idzInvalid columns: z, z. Allowed columns: c                 S   s   g | ]}|d kr|qS )rz   r*   )r>   cr*   r*   r+   r@      rA   zNo valid fields to updatert   z = :zUPDATE z SET z WHERE id = :record_idi  zRecord not foundzRecord updated successfully)rp   updated_fieldszDuplicate entryzfor keyzusers.emaili  validation_erroruM   Email уже используется другим пользователемemailduplicate_value)rv   rp   fieldcodez
users.nameu3   Имя пользователя уже занятоrT   u;   Значение должно быть уникальным)rv   rp   r   zforeign key constraintz cannot add or update a child rowu3   Связанная запись не найденаforeign_key_errorzcannot be nullznot null constraintuG   Обязательное поле не может быть пустымrequired_fieldzinvalid input syntax	incorrectu*   Неверный формат данныхinvalid_formatzDatabase error updating z: r\   uG   Ошибка обновления записи в базе данныхN)rC   rL   loggerinfoitemsr   r6   rD   r]   ra   joinr^   commitrowcountlistkeysre   rollbackrf   lowererror)rJ   rt   ru   r2   rL   rg   r6   rF   rh   rZ   valid_updatesinvalid_columnsrx   ry   set_clausesparamscolumnvaluequeryrH   rn   	error_strr*   r*   r+   update_table_record   s   


$



	


r   z	/register)response_model	user_datac                    s   t | |}tdi |S )z.Register new user (always created as partner).Nr*   )r   register_userr   )r   r2   rH   r*   r*   r+   register  s   r   z/loginc                    s   t | |S )zUser login.)r   
login_user)r   r2   r*   r*   r+   login#  s   r   z/logoutcurrent_userc                    s   t | }tdi |S )zUser logout.Nr*   )r   logout_userr   )r   r2   rH   r*   r*   r+   logout)  s   
r   z/mec                    s   t | S )zGet current user information.)r   from_orm)r   r*   r*   r+   get_current_user_info4  s   
r   c                    s   t | ||S )zUpdate user information.)r   update_user_profile)r   r   r2   r*   r*   r+   update_user_info<  s   r   z/change-passwordpassword_datac                       t | ||}tdi |S )zChange user password.Nr*   )r   change_passwordr   )r   r   r2   rH   r*   r*   r+   r   F     r   z/admin/usersd   skiplimitcurrent_adminc                    s   t || |S )zGet all users (admin only).)r   get_all_users)r   r   r   r2   r*   r*   r+   r   R     r   z/admin/users/{user_id}user_idc                    s   t | |}t|S )zGet user by ID (admin only).)r   get_user_by_idr   r   )r   r   r2   userr*   r*   r+   r   ]  s   
r   c                    s   t | |S )zCreate new user (admin only).)r   create_user_by_admin)r   r   r2   r*   r*   r+   create_userh  s   r   c                    s   t | ||S )zUpdate user (admin only).)r   update_user_by_admin)r   r   r   r2   r*   r*   r+   update_userr  r   r   c                    r   )zDelete user (admin only).Nr*   )r   delete_user_by_adminr   )r   r   r2   rH   r*   r*   r+   delete_user}  r   r   z/google/urlc                     s   t  } t| dS )z#Get Google OAuth authorization URL.auth_url)r    get_oauth_urlr   r   r*   r*   r+   get_google_oauth_url  s   
r   z/google/callback	auth_datac                       t | |tS )z5Handle Google OAuth callback with authorization code.)r    handle_oauth_callbackr   r   r2   r*   r*   r+   google_oauth_callback     r   .zAuthorization code from Google)descriptionr   c                    s$   t d t| d}t||tS )z9Handle Google OAuth callback (GET) with code query param.u'   🔄 Google OAuth GET callback received)r   )r   r   r   r    r   r   )r   r2   r   r*   r*   r+   google_oauth_callback_get  s   

r   z/google/tokenc                    r   )z6Authenticate user with Google ID token (for frontend).)r    authenticate_with_tokenr   r   r*   r*   r+   google_token_auth  r   r   )N)P__doc__loggingtypingr   	functoolsr   r   r   fastapir   r   r   r	   r
   sqlalchemy.ormr   configr   databaser   r1   r   r   modelsr   schemasr   r   r   r   r   r   r   r   r   r   r   r   r   servicesr   r   r    	getLoggerrw   r   routerr/   r(   rf   intboolr,   rb   r0   getrI   ro   postrq   rr   rs   putr   r   r   r   r   r   r   r   r   r   r   deleter   r   r   r   r   r*   r*   r*   r+   <module>   sf   <
		.
   
	

	

	