
    :j             	       8   d Z ddlmZmZmZmZmZmZmZm	Z	 ddl
mZmZ ddlmZm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 dd
lZdd
lZej:                  j=                  ej:                  j?                  ej:                  j?                  ej:                  jA                  e!                         ddl"m#Z#  ede$      Z%e%jM                  d      d        Z'd Z(e%jM                  dddg      d        Z)e%jM                  d      d        Z*e%jM                  d      d        Z+e%jM                  d      d        Z,e%jM                  d      d        Z-e%jM                  d      d        Z.e%jM                  d      d         Z/e%jM                  d!      d"        Z0e%jM                  d#      d$        Z1e%jM                  d%      d&        Z2e%jM                  d'      d(        Z3e%jM                  d)      d*        Z4e%jM                  d+dg      d,        Z5e%jM                  d-dg      d.        Z6e%jM                  d/dg      d0        Z7e%jM                  d1dg      d2        Z8e%jM                  d3dg      d4        Z9e%jM                  d5dg      d6        Z:e%jM                  d7dg      d8        Z;e%jM                  d9d:g      d;        Z<e%jM                  d<d:g      d=        Z=e%jM                  d>d:g      d?        Z>e%jM                  d@d:g      dA        Z?e%jM                  dBdCg      dD        Z@e%jM                  dEdCg      dF        ZAe%jM                  dGdCg      dH        ZBe%jM                  dIdCg      dJ        ZCe%jM                  dKdg      edL               ZDy
)Mze
Admin Routes Blueprint
Contains admin panel functionality, user management, and business management
    )	Blueprintrequestrender_templateredirecturl_forflashjsonifysession)login_requiredcurrent_user)generate_password_hashcheck_password_hash)secure_filename)create_enginetext)sessionmaker)UUID)
quote_plusN)ADMIN_CONFIGadminz/adminc                     t        j                  d      s t        dd       t        t	        d            S d} 	 t
        d   }t        |      }t        dd|      } |       } i }	 | j                  t        d	            j                         }|r|d
   nd
}||d<   	 | j                           |       } 	 | j                  t        d            j                         }|r|d
   nd
}||d<   	 | j                           |       } 	 | j                  t        d            j                         }|r|d
   nd
}	|	|d<   	 | j                           |       } 	 | j                  t        d            j                         }|r|d
   nd
}
|
|d<   	 | j                           |       } 	 | j                  t        d            j                         }|r|d
   nd
}||d<   	 | j                           |       } 	 | j                  t        d            j                         }|r|d
   nd
}||d<   	 | j                           |       } 	 | j                  t        d            j                         }|r<|d
   r7| j                  t        d            j                         }|r|d
   nd
}||d<   nd
|d<   	 | j                           |       } 	 | j                  t        d             j                         }|r:|d
   r5| j                  t        d!            j                         }|r|d
   nd
|d"<   nd#|d"<   	 | j                           |       } 	 | j                  t        d%            j                         }|r|d
   r| j                  t        d&            j                         }|r:|d
   r5| j                  t        d'            j                         }|r|d
   nd
|d(<   no| j                  t        d)            j                         }|r:|d
   r5| j                  t        d*            j                         }|r|d
   nd
|d(<   nd+|d(<   nd+|d(<   	 | j                           |       } 	 | j                  t        d            j                         }|r:|d
   r5| j                  t        d-            j                         }|r|d
   nd
|d.<   nd
|d.<   	 | j                           |       } 	 | j                  t        d0            j                         }|r:|d
   r5| j                  t        d1            j                         }|r|d
   nd
|d2<   nd3|d2<   	 | j                           |       } 	 | j                  t        d5            j                         }|r|d
   nd
|d6<   	 | j                           |       } g }	 | j                  t        d8            j                         }|D ]D  }|j                  d9d:|j                    d;|j"                   t%        |j&                        d<       F 	 	 | j                           |       } 	 | j                  t        d            j                         }|r|d
   r| j                  t        d>            j                         }|D ]y  }|j(                  xs d?}|j*                  d@k(  rdAndB}|j                  |dC|j*                   dDdE|j                    d;|j"                   dF| t%        |j&                        d<       { 	 | j                           |       } 	 | j                  t        dH            j                         }|r.|d
   r)| j                  t        dI            j                         }nZ| j                  t        dJ            j                         }|r.|d
   r)| j                  t        dK            j                         }ng }|D ]5  }|j                  dLdM|j,                  t%        |j&                        d<       7 	 	 | j                          t/        |dO dPQ      dd3 }|j                  dd
      |j                  dd
      |j                  dd
      |j                  d.d
      |j                  d6d
      |j                  d"d
      |j                  d(d
      |j                  d2d
      dR}t1        dS||T      S # t        $ r}t        d|        d
|d<   Y d}~\d}~ww xY w#  Y XxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d|        d
|d<   Y d}~dd}~ww xY w#  Y `xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d|        d
|d<   Y d}~ld}~ww xY w#  Y hxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d|        d
|d<   Y d}~td}~ww xY w#  Y pxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d|        d
|d<   Y d}~|d}~ww xY w#  Y xxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d|        d
|d<   Y d}~d}~ww xY w#  Y xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d|        d
|d<   Y d}~Wd}~ww xY w#  Y SxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d$|        d#|d"<   Y d}~,d}~ww xY w#  Y (xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d,|        d+|d(<   Y d}~hd}~ww xY w#  Y dxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d/|        d
|d.<   Y d}~=d}~ww xY w#  Y 9xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d4|        d3|d2<   Y d}~d}~ww xY w#  Y xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d7|        d
|d6<   Y d}~d}~ww xY w#  Y xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        d=|        Y d}~d}~ww xY w#  Y xY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        dG|        Y d}~Ed}~ww xY w#  Y AxY w# 	 | j                          n#  Y nxY w |       } w xY w# t        $ r}t        dN|        Y d}~d}~ww xY w#  Y xY w# 	 | j                          w #  Y w xY wxY w# t        $ rb}t        dUt3        |              t        dUt3        |       d       	 | r| j                          n#  Y nxY wt1        dSi g T      cY d}~S d}~ww xY w)Vz(Admin dashboard with overview statisticsis_admin>You must be logged in as an administrator to access this page.erroradmin.admin_loginNDATABASE_URLF
autocommit	autoflushbindz!SELECT COUNT(*) FROM beach_placesr   beacheszError counting beaches: z SELECT COUNT(*) FROM restaurantsrestaurantszError counting restaurants: zSELECT COUNT(*) FROM marketsmarketszError counting markets: zSELECT COUNT(*) FROM adventures
adventureszError counting adventures: z1SELECT COUNT(*) FROM users WHERE is_active = trueuserszError counting users: zSELECT COUNT(*) FROM companies	companieszError counting companies: z
                SELECT EXISTS (
                    SELECT FROM information_schema.tables 
                    WHERE table_schema = 'public' AND table_name = 'bookings'
                )
            z
                    SELECT COUNT(*) FROM bookings 
                    WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'
                recent_bookingsz Error counting recent bookings: z
                SELECT EXISTS (
                    SELECT FROM information_schema.tables 
                    WHERE table_schema = 'public' AND table_name = 'messages'
                )
            z5SELECT COUNT(*) FROM messages WHERE status = 'unread'messages   zError counting messages: z
                SELECT EXISTS (
                    SELECT FROM information_schema.tables 
                    WHERE table_schema = 'public' AND table_name = 'reviews'
                )
            z
                    SELECT EXISTS (
                        SELECT column_name FROM information_schema.columns 
                        WHERE table_name = 'reviews' AND column_name = 'status'
                    )
                z5SELECT COUNT(*) FROM reviews WHERE status = 'pending'reviewsa  
                        SELECT EXISTS (
                            SELECT column_name FROM information_schema.columns 
                            WHERE table_name = 'reviews' AND column_name = 'review_status'
                        )
                    z<SELECT COUNT(*) FROM reviews WHERE review_status = 'pending'   zError counting reviews: z
                    SELECT COUNT(*) FROM bookings 
                    WHERE created_at >= CURRENT_DATE - INTERVAL '7 days'
                bookingszError counting bookings: z
                SELECT EXISTS (
                    SELECT FROM information_schema.tables 
                    WHERE table_schema = 'public' AND table_name = 'bookmarks'
                )
            zSELECT COUNT(*) FROM bookmarks	bookmarks
   zError counting bookmarks: z?SELECT COUNT(*) FROM companies WHERE company_status = 'pending'pending_companiesz"Error counting pending companies: z
                SELECT first_name, last_name, email, created_at
                FROM users 
                WHERE created_at >= CURRENT_DATE - INTERVAL '7 days'
                ORDER BY created_at DESC
                LIMIT 5
            zfas fa-user-plus text-successzNew user registered )icontitledescriptiontime_agoz Error fetching user activities: a  
                    SELECT b.booking_id, b.status, b.created_at, u.first_name, u.last_name,
                           bp.beach_name
                    FROM bookings b
                    JOIN users u ON b.user_id = u.user_id
                    LEFT JOIN beach_places bp ON b.beach_place_id = bp.beach_place_id
                    WHERE b.created_at >= CURRENT_DATE - INTERVAL '7 days'
                    ORDER BY b.created_at DESC
                    LIMIT 5
                zUnknown Place	confirmedz"fas fa-calendar-check text-successzfas fa-calendar text-warningzNew booking ()zby z for z#Error fetching booking activities: z
                SELECT EXISTS (
                    SELECT column_name FROM information_schema.columns 
                    WHERE table_name = 'companies' AND column_name = 'created_at'
                )
            z
                    SELECT company_name, created_at
                    FROM companies 
                    WHERE created_at >= CURRENT_DATE - INTERVAL '7 days'
                    ORDER BY created_at DESC
                    LIMIT 5
                z
                    SELECT EXISTS (
                        SELECT column_name FROM information_schema.columns 
                        WHERE table_name = 'companies' AND column_name = 'create_date'
                    )
                a$  
                        SELECT company_name, create_date as created_at
                        FROM companies 
                        WHERE create_date >= CURRENT_DATE - INTERVAL '7 days'
                        ORDER BY create_date DESC
                        LIMIT 5
                    zfas fa-building text-primaryzNew company registeredz#Error fetching company activities: c                 &    | j                  dd      S )Nr4    )get)xs    9/var/www/bookbeach.app/backend/app/routes/admin_routes.py<lambda>z!admin_dashboard.<locals>.<lambda>  s    aeeJ6K     T)keyreverse)total_userstotal_companiestotal_beachestotal_bookingsr/   r(   r*   r-   zadmin/dashboard.html)statsrecent_activitieszError loading dashboard: )r
   r9   r   r   r   r   r   r   executer   fetchone	Exceptionprintclosefetchallappend
first_name	last_namer4   
created_at
beach_namestatuscompany_namesortedr   str)dbr   engineSessionLocalrD   resultbeach_counterestaurant_countmarket_countadventure_count
user_countcompany_counttable_checkr'   column_check
activitiesrecent_usersuserrecent_booking_activitybooking
place_namestatus_iconrecent_companiescompanytemplate_statss                             r;   admin_dashboardrl      s    ;;z"NPWX 3455	B_W#N3|,#uFS^ 	 ZZ%H IJSSUF'-&)1K*E)

 B	 ZZ%G HIRRTF,2vay#3E- 

 B	 ZZ%C DENNPF(.6!9AL+E)

 B	 ZZ%F GHQQSF+1fQiqO"1E,

 B	 ZZ%X YZcceF&,!J'E'N

 B	 ZZ%E FGPPRF)/F1IQM!.E+

 B	 **T + & 
 (*  {1~D * %  hj  06&)1+:'(+,'(

 B	 **T + & 
 (*  {1~D)`$abkkm17F1IQj!$&j!

 B-	 **T + & 
 (*  {1~!zz$ 0 +  
 hj   LOZZ-d(efooqF4:vayE)$ $&::d 4 / $
 #(* ! $Q!#D1o,p!q!z!z!|8>6!9Ai(+-i(#%i 

 B	 **T + & 
 (*  {1~D * %  hj  28F1IQj!$%j!

 B	 **T + & 
 (*  {1~D)I$JKTTV28VAYak"%'k"

 B	 ZZ%f ghqqsF6<!E%&

 B 
	 ::d , '  (*  % !!;2&*oo%6a7G#H ( 9	# 
 B%	 **T + & 
 (*  {1~*,**T 	; 	6 	+ hj (  7 G!(!3!3!FJJQ..\gJg"F  nLK%% +#00@!B),W-?-?,@'BSBSATTYZdYe'f$,W-?-?$@	' 
 B3	 ::d , ' 
 (*  Q#%::d 4 / $ hj !  "zz$ 0 +  
 hj   LO')zz$ 8 3 ( #(* % (*$+ !!:5#*#7#7 ();); <	# 

 J,KUYZ[^\^_
 !99Wa0$yya8"YYy!4#ii
A6!&+>!B		*a0yyA.;2	
 5^_ijjI  	!,QC01 E)	!
B  	%045#$E- 	%
B  	!,QC01 E)	!
B  	$/s34"#E,	$
B  	*1#./E'N	
B  	#.qc23!"E+	#
B*  	)4QC89'(E#$	)
B"  	#-aS12 "E*	#
BN  	",QC01!E)	"
B(  	"-aS12 !E*	"
B   	$.qc23!#E+	$
B  	+6qc:;)*E%&	+
B,  	:4QC899	:

B@  	=7s;<<	=

B^  	=7s;<<	=

&  	W)#a&23)#a&2G<	
	5RSUVV	Ws  +w %6c c? ,w 46d, +e ;w 6f :f- 
w 6g 	h w !6h1 i (w 06j 'j2 7w ?A+k +l	 ;w A)l6 -m  =w Dn n7 w  A)o$ 
p w "A)p; q% w $4r r< )	w 3A1s) $t &t 6w >Ct; u  $w ,C,v v: v2 *B*w 	c<c71d 7c<<d ?dw d)	dd)dd))w ,	e5ee ee ew f  e10f 1e53f  w 	f*f%f5 %f**f5 -f2/w 5g7ggg
gw 	h#g<6h <hh h	w h.hh.h#!h..w 1	i:ii# ii# i w #j%i65j6i:8jw 	j/j*$j: *j//j: 2j74w :k<kkkkw 	l(l;l ll 	lw l3l$#l3$l(&l33w 6	m?mm( mm(  m%"w (n
*m;:n
;m?=n

w 	n4n/)n? /n44n? 7n<9w ?o!oo!oo!!w $	p-p p pp pw p8p)(p8)p-+p88w ;	q"qq- q""q- %q*'w -r/r ?r rrw 	r9r4.s 4r99s <s>w s&ss&ss&&w )	t2t t tt tw t8t)(t8)t-+t88w ;	uuu( uu(  u%"w (v
*u;:v
;u?=v

w 	v/v*$v: *v//v: 2v74w :w<wwwww 	y /x=x#"x=#x'%x=7y=yc                    ddl m } | syt        | d      r>|j                         }| j                  r|j	                  | j                        }|| z
  }ny|j
                  dkD  r|j
                  dkD  r!|j
                  dz  }| d|dkD  rd	 dS d
 dS |j
                  dkD  r!|j
                  dz  }| d|dkD  rd	 dS d
 dS |j
                   d|j
                  dkD  rd	 dS d
 dS |j                  dkD  r!|j                  dz  }| d|dkD  rd	 dS d
 dS |j                  dkD  r!|j                  dz  }| d|dkD  rd	 dS d
 dS y)z2Convert datetime to human-readable time ago stringr   )datetimeUnknownreplace)tzinfo   z month   sr8   z ago   z weekz dayi  z hour<   z minutezJust now)rn   hasattrnowrq   rp   daysseconds)dtrn   rx   diffmonthsweekshoursminutess           r;   r4   r4     s   ! r9lln99++RYY+/CRxyy1}99r>YY"_FXV6A:C#>dCC2#>dCCYY]IINEWE#!;4@@!;4@@ii[DIIMS$B$GGr$B$GG		$UQYc7t<<B7t<<		,,"$'1#!=TBB"!=TBBr=   z/admin/loginGETPOST)methodsc                     t         j                  dk(  r~t         j                  d   } t         j                  d   }| t        d   k(  rP|t        d   k(  rDdt        d<   | t        d<   d	t        d
<   dt        d<   t        dd       t        t        d            S 	 t        d   }t        |      }t        dd|      } |       }|j                  t        d      d| i      j                         }|j                          |rt        |j                  |      rsdt        d<   | t        d<   t!        |j"                        t        d<   t!        |j"                        t        d
<   dt        d<   t        dd       t        t        d            S t        dd       t'        d      S # t$        $ r"}t        dt!        |       d       Y d}~=d}~ww xY w)zAdmin login pager   usernamepasswordADMIN_USERNAMEADMIN_PASSWORDTadmin_logged_inadmin_usernamer   user_idr   zAdmin login successful!successzadmin.admin_dashboardr   Fr   aW  
                SELECT u.user_id, u.password_hash, u.first_name, u.last_name, u.email
                FROM users u
                JOIN user_roles ur ON u.role_id = ur.role_id
                WHERE (u.first_name = :username OR u.email = :username)
                AND u.is_active = true
                AND ur.role_name = 'admin'
            admin_user_idzDatabase error during login: r   NzInvalid admin credentials.z
login.html)r   methodformr   r
   r   r   r   r   r   rF   r   rG   rJ   r   password_hashrT   r   rH   r   )r   r   r   rV   rW   rU   user_resultrZ   s           r;   admin_loginr     s    ~~<<
+<<
+ |$455(lScFd:d)-G%&(0G$%!(GI"&GJ+Y7G$;<==	E'7L"<0F'5EPVWLB**T + & x(* +3(*  HHJ2;3L3LhW-1)*,4()+.{/B/B+C(%()<)<%=	"&*
#/;(? @AA 	*G4 <((  	E1#a&:GDD	Es   C.F 	G	'GG	z/admin/usersc                  P   t        j                  d      s t        dd       t        t	        d            S t
        j                  j                  dd      j                         } t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }dt
        j                  v xs& dt
        j                  v xs dt
        j                  v }|st        d	g d
dd
ddddddd      S g }d
}d}d
}d}d}	d}
d}	 t        d   }t        |      }t        dd|      } |       }t
        j                  j                  dd
t              }d}|d
z
  |z  }g }i }| r|j                  d       d|  d|d<   |r|j                  d       ||d<   |r|dk(  }|j                  d       ||d<   |rddj                  |      z   nd}d| d}|j                  t!        |      |      j#                         }|r|d   nd}d| d}||d <   ||d!<   |j                  t!        |      |      j%                         }g }|D ]  }|j                  |j&                  |j(                  |j*                  xs d d"|j,                  xs d j                         |j.                  xs d#|j0                  rdnd$|j2                  r|j2                  j5                  d%      nd&|j6                  xs d&|j8                  d'        ||z   d
z
  |z  }|d
kD  }||k  }	|r|d
z
  nd}
|	r|d
z   nd}|j;                          t        d	||||||	|
|| ||      S # t<        $ r2}t        d(t?        |       d       g }d
}d}d
}d}d}	d}
d}Y d}~Md}~ww xY w))zManage usersr   r   r   r   searchr8   rolerQ   zadmin/users.htmlrs   r   FN)r%   pagetotal_counttotal_pageshas_prevhas_nextprev_numnext_numsearch_termrole_filterstatus_filterr   r   r   typer.   zk(u.email ILIKE :search OR u.first_name ILIKE :search OR u.last_name ILIKE :search OR u.phone ILIKE :search)%zur.role_name = :roleActivezu.is_active = :is_active	is_activeWHERE  AND z
            SELECT COUNT(*) 
            FROM users u
            LEFT JOIN user_roles ur ON u.role_id = ur.role_id
            z	
        a  
            SELECT u.user_id, u.email, u.first_name, u.last_name, 
                   ur.role_name, u.is_active, u.created_at,
                   u.is_email_verified, u.phone
            FROM users u
            LEFT JOIN user_roles ur ON u.role_id = ur.role_id
            zX
            ORDER BY u.created_at DESC
            LIMIT :limit OFFSET :offset
        limitoffsetr0   zNo RoleInactivez%Y-%m-%dzN/A)idemailnamer   rQ   rO   phoneemail_verifiedzError loading users: ) r
   r9   r   r   r   r   argsstripr   r   r   r   intrL   joinrF   r   rG   rK   r   r   rM   rN   	role_namer   rO   strftimer   is_email_verifiedrJ   rH   rT   )r   r   r   is_search_request
users_datar   r   r   r   r   r   r   r   rV   rW   rU   per_pager   where_conditionsparamsr   where_clausecount_querycount_resultusers_queryusers_resultrd   rZ   s                               r;   r%   r%     s    ;;z"NPWX 3455 ,,""8R0668K,,""62.446KLL$$Xr288:M !GLL0fFgll4JfhZaZfZfNf 1#%"#)*)*&+&+&*&*)+)++-/ 	/ JDKKHHHHZ#N3|,#uFS^ ||4(h& ##  %R  S!";-q1F8##$:;(F6N%1I##$>?"+F;DTx',,/?"@@Z\ N 		 zz${"3V<EEG)5l1o1 N 		 #w!xzz${"3V<EEG
  
	Dll??0b14>>3GR2HIOOQ3)&*nn(*FJoodoo66zB[`,u"&"8"8	 	
	 #X-1h>!8+%'4!8T'4!8T

 -)"%0%0"*"*"*"*%0%0'46 6  	%c!fX.8
	s   $H/M* *	N%3(N  N%z/admin/settingsc                      t        j                  d      s t        dd       t        t	        d            S t        d      S )zView system settingsr   r   r   r   zadmin/settings.html)r
   r9   r   r   r   r    r=   r;   settingsr     s;     ;;z"NPWX 3455 011r=   z/admin/reportsc                     t        j                  d      s t        dd       t        t	        d            S 	 t
        d   } t        |       }t        dd|      } |       }ddddd	d
d
d
d
d	g d}|j                  t        d            j                         }|r|d
   nd}|j                  t        d            j                         }|r|d
   nd}|rd
dlm}	m}
 |	j                         j                         }| |
|j                               z
  }|j!                  d      }|j!                  dd      }d| dd| dd| dd| dd	}|j#                         D ]d  \  }}|j                  t        d| d            j                         }|s5t%        |d
   xs d
      |d   |<   t'        |d   xs d
      |d   |<   f |rT|rR|j                  t        d            j)                         }|D cg c]  }|j*                  |j,                  d c}|d<   |j/                          t5        d|       S c c}w # t0        $ r2}t        dt3        |       d       ddddd	d
d
d
d
d	g d}Y d}~Hd}~ww xY w)!zView reports and analyticsr   r   r   r   r   Fr   g        )today	this_week
this_month	this_yearr   )revenuer,   top_beachesz
            SELECT EXISTS (
                SELECT FROM information_schema.tables 
                WHERE table_schema = 'public' AND table_name = 'bookings'
            )
        z
            SELECT EXISTS (
                SELECT FROM information_schema.tables 
                WHERE table_schema = 'public' AND table_name = 'beaches'
            )
        )rn   	timedelta)ry   rs   )day)monthr   zbooking_date = ''zbooking_date >= 'z
                    SELECT COALESCE(SUM(total_amount), 0) as revenue,
                           COUNT(*) as count
                    FROM bookings 
                    WHERE zV
                    AND booking_status IN ('confirmed', 'completed')
                r   r,   au  
                SELECT b.beach_name, COUNT(bk.booking_id) as booking_count
                FROM beaches b
                LEFT JOIN bookings bk ON b.beach_id = bk.beach_id
                WHERE bk.booking_status IN ('confirmed', 'completed')
                GROUP BY b.beach_id, b.beach_name
                ORDER BY booking_count DESC
                LIMIT 5
            )r   r,   r   zError loading reports: Nzadmin/reports.html)reports)r
   r9   r   r   r   r   r   r   rF   r   rG   rn   r   rx   dateweekdayrp   itemsfloatr   rK   rP   booking_countrJ   rH   rT   r   )r   rV   rW   rU   reports_databookings_check_resultbookings_existsbeaches_check_resultbeaches_existsrn   r   r   
week_startmonth_start
year_startrevenue_queriesperiod	conditionrX   top_beaches_resultbeachrZ   s                         r;   r   r     s    ;;z"NPWX 3455l
#N3|,#uFS^
 !"!	 	 
" !#

4 1 , !
 hj 	 7L/2QV!zz$ 0 +  
 hj 	 5I-a0e4LLN'')E!@@J--A-.KQA6J ,E7!40A> 1+a@0A>	O &5%:%:%< K!	D . %+ &	* %  hj  6;F1IN6KL+F37:6!9>7JL,V4K ~!#D 2 - " (*  0+ ))u7J7JK+L'
 	
* /FF5+  
'Ax0': !"!	 	 

s1   EH? A"H? 7 H:H? :H? ?	I:(I55I:z/admin/companiesc                  "   t        j                  d      s t        dd       t        t	        d            S t
        j                  j                  dd      j                         } t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }dt
        j                  v xs& dt
        j                  v xs dt
        j                  v }|st        d	g d
dd
dddddddg       S 	 t        d   }t        |      }t        dd|      } |       }d}t
        j                  j                  dd
t              }	d}
|	d
z
  |
z  }g }i }| r|j                  d       d|  d|d<   |r|j                  d       ||d<   |r|j                  d       ||d<   |rddj                  |      z   nd}d| }|j                  t!        |      |      j#                         }|r|d   nd}d| d| d}|
|d<   ||d<   |j                  t!        |      |      j%                         }||
z   d
z
  |
z  }|	d
kD  }|	|k  }|r|	d
z
  nd}|r|	d
z   nd}g }	 |j                  t!        d             j%                         }|D cg c]  }|d   |d
   d! }}|j+                          t)        d#t-        |       d$|        t        d	||	||||||| |||      S c c}w # t&        $ r}t)        d"|        Y d}~cd}~ww xY w# t&        $ re}t        d%t/        |       d       t)        d&t/        |              ddl}|j3                          t        d	g d
dd
dddd| ||g       cY d}~S d}~ww xY w)'zManage companiesr   r   r   r   r   r8   rQ   
country_idzadmin/companies.htmlrs   r   FN)r&   r   r   r   r   r   r   r   r   company_statusselected_country_id	countriesr   r   a  
            SELECT 
                c.company_id,
                c.company_name,
                c.website,
                c.email AS contact_email,
                c.phone AS contact_phone,
                c.company_logo_path AS logo_path,
                c.create_date AS created_at,
                c.update_date AS updated_at,
                c.vat_number,
                c.city,
                c.province,
                c.country_id,
                c.company_status,
                co.country_name,
                COALESCE(beach_counts.count, 0) AS beaches_count,
                COALESCE(restaurant_counts.count, 0) AS restaurants_count,
                COALESCE(market_counts.count, 0) AS markets_count,
                COALESCE(adventure_counts.count, 0) AS adventures_count
            FROM companies c
            LEFT JOIN countries co ON c.country_id = co.country_id
            LEFT JOIN (
                SELECT company_id, COUNT(*) AS count
                FROM beach_places
                GROUP BY company_id
            ) beach_counts ON c.company_id = beach_counts.company_id
            LEFT JOIN (
                SELECT company_id, COUNT(*) AS count
                FROM restaurants
                GROUP BY company_id
            ) restaurant_counts ON c.company_id = restaurant_counts.company_id
            LEFT JOIN (
                SELECT company_id, COUNT(*) AS count
                FROM markets
                GROUP BY company_id
            ) market_counts ON c.company_id = market_counts.company_id
            LEFT JOIN (
                SELECT company_id, COUNT(*) AS count
                FROM adventures
                GROUP BY company_id
            ) adventure_counts ON c.company_id = adventure_counts.company_id
        r   r   r.   zn(c.company_name ILIKE :search OR c.email ILIKE :search OR c.phone ILIKE :search OR c.vat_number ILIKE :search)r   zc.company_status = :statuszc.country_id = :country_idr   r   z!SELECT COUNT(*) FROM companies c z
            zU
            ORDER BY c.company_name
            LIMIT :limit OFFSET :offset
        r   r   zDSELECT country_id, country_name FROM countries ORDER BY country_name)r   country_namezError loading countries: zCompanies route - Found z companies, total count: zError loading companies: zError in companies route: )r
   r9   r   r   r   r   r   r   r   r   r   r   r   rL   r   rF   r   rG   rK   rH   rI   rJ   lenrT   	traceback	print_exc)r   r   r   r   r   rV   rW   rU   
base_queryr   r   r   r   r   r   r   r   r   paginated_queryr&   r   r   r   r   r   r   countries_resultrowrZ   r   s                                 r;   r&   r&   .  s    ;;z"NPWX 3455 ,,""8R0668K\\%%h399;N!,,**<<BBD !GLL0lH4LlP\`g`l`lPl 5')"#)*)*&+&+&*&*)+,.13')+ 	+Q+#N3|,#uFS^*
Z ||4(h& ##  %U  V!";-q1F8##$@A-F8##$@A#6F< DTx',,/?"@@Z\ :,Hzz${"3V<EEG)5l1o1L N 	 #w!xJJtO4f=FFH	 #X-1h>!8+%'4!8T'4!8T 		3!zz$/u*vw   A   A   CScdCAAGdId 	
(Y(88QR]Q^_`5'0"&)4)4&.&.&.&.)4,:1D'02 	2 e 	3-aS122	3*  +)#a&2G<*3q6(345')"#)*)*&+&+&*&*)4,:1D')+ 	++s]   EL  5,K< !K73K< 5AL  7K< <	LLL  LL   	N)AN	N	Nz/admin/beachesc                  <   t        j                  d      s t        dd       t        t	        d            S t
        j                  j                  dd      j                         } dt
        j                  v }|st        dg dd	dd
d
ddd
      S 	 t        d   }t        |      }t        d
d
|      } |       }t
        j                  j                  ddt              }d}|dz
  |z  }g }	i }
| r|	j                  d       d|  d|
d<   |	rddj                  |	      z   nd}d| }|j                  t!        |      |
      j#                         }|r|d	   nd	}d| d}||
d<   ||
d<   |j                  t!        |      |
      j%                         }||z   dz
  |z  }|dkD  }||k  }|r|dz
  nd}|r|dz   nd}|j'                          t        d||||||||| 
      S # t(        $ r7}t        dt+        |       d       t        dg dd	dd
d
dd| 
      cY d}~S d}~ww xY w)zManage beachesr   r   r   r   r   r8   zadmin/beaches.htmlrs   r   FN)	r!   r   r   r   r   r   r   r   r   r   r   r   r   r.   z6(bp.beach_name ILIKE :search OR bp.city ILIKE :search)r   r   r   z%SELECT COUNT(*) FROM beach_places bp as  
            SELECT bp.beach_place_id, bp.beach_name, bp.address, bp.city,
                   c.company_name, co.country_name, bp.enable_beach,
                   bp.created_at, bp.updated_at
            FROM beach_places bp
            LEFT JOIN companies c ON bp.company_id = c.company_id
            LEFT JOIN countries co ON bp.country_id = co.country_id
            zT
            ORDER BY bp.beach_name
            LIMIT :limit OFFSET :offset
        r   r   zError loading beaches: r
   r9   r   r   r   r   r   r   r   r   r   r   r   rL   r   rF   r   rG   rK   rJ   rH   rT   )r   r   r   rV   rW   rU   r   r   r   r   r   r   r   r   r   beaches_queryr!   r   r   r   r   r   rZ   s                          r;   r!   r!     s    ;;z"NPWX 3455 ,,""8R0668K !GLL0 3%'"#)*)*&+&+&*&*)+	- 		-M6#N3|,#uFS^ ||4(h& ##$\]!";-q1F8DTx',,/?"@@Z\ >l^Lzz${"3V<EEG)5l1o1 N 	
 #w!x**T-0&9BBD #X-1h>!8+%'4!8T'4!8T

3%,"&)4)4&.&.&.&.)4	6 		6  6'Ax0':3%'"#)*)*&+&+&*&*)4	6 		66   EG 	H$,HHHz/admin/restaurantsc                  <   t        j                  d      s t        dd       t        t	        d            S t
        j                  j                  dd      j                         } dt
        j                  v }|st        dg dd	dd
d
ddd
      S 	 t        d   }t        |      }t        d
d
|      } |       }t
        j                  j                  ddt              }d}|dz
  |z  }g }	i }
| r|	j                  d       d|  d|
d<   |	rddj                  |	      z   nd}d| }|j                  t!        |      |
      j#                         }|r|d	   nd	}d| d}||
d<   ||
d<   |j                  t!        |      |
      j%                         }||z   dz
  |z  }|dkD  }||k  }|r|dz
  nd}|r|dz   nd}|j'                          t        d||||||||| 
      S # t(        $ r7}t        dt+        |       d       t        dg dd	dd
d
dd| 
      cY d}~S d}~ww xY w)zManage restaurantsr   r   r   r   r   r8   zadmin/restaurants.htmlrs   r   FN)	r"   r   r   r   r   r   r   r   r   r   r   r   r   r.   zk(r.restaurant_name ILIKE :search OR r.city ILIKE :search OR r.phone ILIKE :search OR r.email ILIKE :search)r   r   r   z#SELECT COUNT(*) FROM restaurants r an  
            SELECT r.restaurant_id, r.restaurant_name, r.address, r.city,
                   c.company_name, co.country_name, r.phone, r.email,
                   r.created_at, r.updated_at
            FROM restaurants r
            LEFT JOIN companies c ON r.company_id = c.company_id
            LEFT JOIN countries co ON r.country_id = co.country_id
            zX
            ORDER BY r.restaurant_name
            LIMIT :limit OFFSET :offset
        r   r   zError loading restaurants: r   )r   r   r   rV   rW   rU   r   r   r   r   r   r   r   r   r   restaurants_queryr"   r   r   r   r   r   rZ   s                          r;   r"   r"   O  s    ;;z"NPWX 3455 ,,""8R0668K !GLL0 7)+"#)*)*&+&+&*&*)+	- 		-M6#N3|,#uFS^ ||4(h& ##  %R  S!";-q1F8DTx',,/?"@@Z\ <L>Jzz${"3V<EEG)5l1o1! N 	
 #w!xjj&7!8&AJJL #X-1h>!8+%'4!8T'4!8T

7)4"&)4)4&.&.&.&.)4	6 		6  6+CF84g>7)+"#)*)*&+&+&*&*)4	6 		66r   z'/admin/restaurants/edit/<restaurant_id>c           	         t        j                  d      s t        dd       t        t	        d            S d}	 t
        d   }t        |      }t        dd|      } |       }d	dl}d	dl	}|j                  j                  |j                  j                  |j                  j                  |j                  j                  t                                 d	d
lm} d	dlm} d	dlm}	 d	dlm}
 |j/                  |      j1                  |j2                  | k(        j5                         }|r|j6                  }|s4t        dd       t        t	        d            |r	 |j9                          S S |j/                  |      j;                  |j<                        j?                         }|j/                  |	      j;                  |	j@                        j?                         }|j/                  |
      j;                  |
jB                        j?                         }tE        d||||      |r	 |j9                          S S #  Y S xY w#  Y S xY w# tF        $ rS}tI        d|        t        dd       t        t	        d            cY d}~|r	 |j9                          S #  Y S xY wS d}~ww xY w# |r	 |j9                          w #  Y w xY ww xY w)zEdit restaurantr   r   r   r   Nr   Fr   r   )
RestaurantCompanyCountry
BeachPlacezRestaurant not found.zadmin.restaurantszadmin/edit_restaurant.html)
restaurantr&   r   beach_placesz Error fetching restaurant data: z1An error occurred while fetching restaurant data.)%r
   r9   r   r   r   r   r   r   sysospathrL   dirnameabspath__file__app.models.businessr   app.models.companyr   app.models.userr   app.models.beachr   queryfilterrestaurant_idfirstphotosrJ   order_byrR   allr   rP   r   rH   rI   )r
  rU   r   rV   rW   r   r   r   r   r   r   r   _r&   r   r   rZ   s                    r;   edit_restaurantr    s\    ;;z"NPWX 3455	B0#N3|,#uFS^ 	8Q(RST2.+/ XXj)001I1I]1Z[aac
!!A)73G$789* 
 % HHW%..w/C/CDHHJ	 HHW%..w/C/CDHHJ	 xx
+44Z5J5JKOOQ;(2'0'0*6	8 
   6045A7K 3455
	 6
 
	 ss   DI H7+B7I %H>7H;>I	J!-J;J!<J$ JJJ!!J$ $K(J98K9J=;Kz/admin/beaches/edit/<beach_id>c           	      
   t        j                  d      s t        dd       t        t	        d            S d}	 t
        d   }t        |      }t        dd|      } |       }d	dl}d	dl	}|j                  j                  |j                  j                  |j                  j                  |j                  j                  t                                 d	d
lm} d	dlm} d	dlm}	 |j+                  |      j-                  |j.                  | k(        j1                         }
|
r|
j2                  }|
s4t        dd       t        t	        d            |r	 |j5                          S S |j+                  |      j7                  |j8                        j;                         }|j+                  |	      j7                  |	j<                        j;                         }t?        d|
||      |r	 |j5                          S S #  Y S xY w#  Y S xY w# t@        $ rS}tC        d|        t        dd       t        t	        d            cY d}~|r	 |j5                          S #  Y S xY wS d}~ww xY w# |r	 |j5                          w #  Y w xY ww xY w)z
Edit beachr   r   r   r   Nr   Fr   r   r   r   r   zBeach not found.zadmin.beacheszadmin/edit_beach.html)r   r&   r   zError fetching beach data: z,An error occurred while fetching beach data.)"r
   r9   r   r   r   r   r   r   r   r   r   rL   r  r  r  r  r   r  r   r  r   r  r	  beach_place_idr  r  rJ   r  rR   r  r   r   rH   rI   )beach_idrU   r   rV   rW   r   r   r   r   r   r   r  r&   r   rZ   s                  r;   
edit_beachr    s(    ;;z"NPWX 3455	B+#N3|,#uFS^ 	8Q(RST/.+ $++J,E,E,QRXXZA$g.GO45" 
  HHW%..w/C/CDHHJ	 HHW%..w/C/CDHHJ	6#('0'02 
   2+A3/0<gF011
	 2
 
	 ss   DH G8%A>H &G?8G<?H	I"-I<I"=I% III""I% %J)I:9J:I><Jz/admin/marketsc                  <   t        j                  d      s t        dd       t        t	        d            S t
        j                  j                  dd      j                         } dt
        j                  v }|st        dg dd	dd
d
ddd
      S 	 t        d   }t        |      }t        d
d
|      } |       }t
        j                  j                  ddt              }d}|dz
  |z  }g }	i }
| r|	j                  d       d|  d|
d<   |	rddj                  |	      z   nd}d| }|j                  t!        |      |
      j#                         }|r|d	   nd	}d| d}||
d<   ||
d<   |j                  t!        |      |
      j%                         }||z   dz
  |z  }|dkD  }||k  }|r|dz
  nd}|r|dz   nd}|j'                          t        d||||||||| 
      S # t(        $ r7}t        dt+        |       d       t        dg dd	dd
d
dd| 
      cY d}~S d}~ww xY w)zManage marketsr   r   r   r   r   r8   zadmin/markets.htmlrs   r   FN)	r#   r   r   r   r   r   r   r   r   r   r   r   r   r.   zO(m.market_name ILIKE :search OR m.phone ILIKE :search OR m.email ILIKE :search)r   r   r   zSELECT COUNT(*) FROM markets m ab  
            SELECT m.market_id, m.market_name, m.address, m.city,
                   c.company_name, co.country_name, m.phone, m.email,
                   m.created_at, m.updated_at
            FROM markets m
            LEFT JOIN companies c ON m.company_id = c.company_id
            LEFT JOIN countries co ON m.country_id = co.country_id
            zT
            ORDER BY m.market_name
            LIMIT :limit OFFSET :offset
        r   r   zError loading markets: r   )r   r   r   rV   rW   rU   r   r   r   r   r   r   r   r   r   markets_queryr#   r   r   r   r   r   rZ   s                          r;   r#   r#   ,  s    ;;z"NPWX 3455 ,,""8R0668K !GLL0 3%'"#)*)*&+&+&*&*)+	- 		-M6#N3|,#uFS^ ||4(h& ##$uv!";-q1F8DTx',,/?"@@Z\ 8~Fzz${"3V<EEG)5l1o1 N 	
 #w!x**T-0&9BBD #X-1h>!8+%'4!8T'4!8T

3%,"&)4)4&.&.&.&.)4	6 		6  6'Ax0':3%'"#)*)*&+&+&*&*)4	6 		66r   z/admin/adventuresc                  <   t        j                  d      s t        dd       t        t	        d            S t
        j                  j                  dd      j                         } dt
        j                  v }|st        dg dd	dd
d
ddd
      S 	 t        d   }t        |      }t        d
d
|      } |       }t
        j                  j                  ddt              }d}|dz
  |z  }g }	i }
| r|	j                  d       d|  d|
d<   |	rddj                  |	      z   nd}d| }|j                  t!        |      |
      j#                         }|r|d	   nd	}d| d}||
d<   ||
d<   |j                  t!        |      |
      j%                         }||z   dz
  |z  }|dkD  }||k  }|r|dz
  nd}|r|dz   nd}|j'                          t        d||||||||| 
      S # t(        $ r7}t        dt+        |       d       t        dg dd	dd
d
dd| 
      cY d}~S d}~ww xY w)zManage adventuresr   r   r   r   r   r8   zadmin/adventures.htmlrs   r   FN)	r$   r   r   r   r   r   r   r   r   r   r   r   r   r.   zR(a.adventure_name ILIKE :search OR a.phone ILIKE :search OR a.email ILIKE :search)r   r   r   z"SELECT COUNT(*) FROM adventures a a  
            SELECT a.adventure_id, a.adventure_name, a.address, a.city,
                   c.company_name, co.country_name, a.phone, a.email,
                   a.duration_minutes, a.max_participants, a.price,
                   a.created_at, a.updated_at
            FROM adventures a
            LEFT JOIN companies c ON a.company_id = c.company_id
            LEFT JOIN countries co ON a.country_id = co.country_id
            zW
            ORDER BY a.adventure_name
            LIMIT :limit OFFSET :offset
        r   r   zError loading adventures: r   )r   r   r   rV   rW   rU   r   r   r   r   r   r   r   r   r   adventures_queryr$   r   r   r   r   r   rZ   s                          r;   r$   r$     s    ;;z"NPWX 3455 ,,""8R0668K !GLL0 6(*"#)*)*&+&+&*&*)+	- 		-N6#N3|,#uFS^ ||4(h& ##$xy!";-q1F8DTx',,/?"@@Z\ ;<.Izz${"3V<EEG)5l1o1  N 	 #w!xZZ%5 6?HHJ
 #X-1h>!8+%'4!8T'4!8T

6(2"&)4)4&.&.&.&.)4	6 		6  6*3q6(3W=6(*"#)*)*&+&+&*&*)4	6 		66r   z/admin/markets/edit/<market_id>c                    t        j                  d      s t        dd       t        t	        d            S d}	 t
        d   }t        |      }t        dd|      } |       }d	dl}d	dl	}t        d
t                t        t        d       t        t	        dt                    |r	 |j                          S S #  Y S xY w# tL        $ rS}t        d|        t        dd       t        t	        d            cY d}~|r	 |j                          S #  Y S xY wS d}~ww xY w# |r	 |j                          w #  Y w xY ww xY w)zEdit marketr   r   r   r   Nr   Fr   r   BEACH DESIGN ERROR: admin.edit_beachr  zadmin.marketszError fetching market data: z-An error occurred while fetching market data.)'r
   r9   r   r   r   r   r   r   r   r   rI   	error_msgr  rJ   r   rL   r  r  r  r  Marketr  r   r  r   r  r   r  r	  	market_idr  r  r  rR   r  r   rP   r   rH   )r  rU   r   rV   rW   r   r   r  r   r   r   marketr  r&   r   r   rZ   s                    r;   edit_marketr!    s4    ;;z"NPWX 3455	B6#N3|,#uFS^ 	$YK01i! 2XFGH 
   2,QC01=wG011
	 2
 
	 s`   A,C (B::B>	D
-D7D8D  ?DDDD   D=$D54D=5D97D=z%/admin/adventures/edit/<adventure_id>c           	         t        j                  d      s t        dd       t        t	        d            S d}	 t
        d   }t        |      }t        dd|      } |       }d	dl}d	dl	}|j                  j                  |j                  j                  |j                  j                  |j                  j                  t                                 d	d
lm} d	dlm} d	dlm}	m}
 d	dlm} |j1                  |      j3                  |j4                  | k(        j7                         }|r|j8                  }|s4t        dd       t        t	        d            |r	 |j;                          S S |j1                  |      j=                  |j>                        jA                         }|j1                  |	      j=                  |	jB                        jA                         }|j1                  |
      j=                  |
jD                        jA                         }|j1                  |      j=                  |jF                        jA                         }tI        d|||||      |r	 |j;                          S S #  Y S xY w#  Y S xY w# tJ        $ rS}tM        d|        t        dd       t        t	        d            cY d}~|r	 |j;                          S #  Y S xY wS d}~ww xY w# |r	 |j;                          w #  Y w xY ww xY w)zEdit adventurer   r   r   r   Nr   Fr   r   )	Adventurer   )r   Currencyr   zAdventure not found.admin.adventureszadmin/edit_adventure.html)	adventurer&   r   
currenciesr   zError fetching adventure data: z0An error occurred while fetching adventure data.)'r
   r9   r   r   r   r   r   r   r   r   r   rL   r  r  r  r  r#  r  r   r  r   r$  r  r   r  r	  adventure_idr  r  rJ   r  rR   r  r   currency_namerP   r   rH   rI   )r(  rU   r   rV   rW   r   r   r#  r   r   r$  r   r&  r  r&   r   r'  r   rZ   s                      r;   edit_adventurer*  F  s    ;;z"NPWX 3455	B4#N3|,#uFS^ 	8Q(RST1.5/ HHY'..y/E/E/UV\\^	  A('2G$6782 
 - HHW%..w/C/CDHHJ	 HHW%..w/C/CDHHJ	 XXh'001G1GHLLN
 xx
+44Z5J5JKOOQ:'0'0'0(2*68 
   5/s34@'J 2344
	 5
 
	 ss   DJ  I2-C0J   I92I69I= 	K	-K6K7K >KKKK K<#K43K<4K86K<z'/admin/adventures/update/<adventure_id>c                    t        j                  d      s t        dd       t        t	        d            S 	 t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  d	d      j                         }t
        j                  j                  d
d      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }	t
        j                  j                  dd      j                         }
t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }t
        j                  j                  dd      j                         }|r|s"t        dd       t        t	        d|             S t        d   }t        |      }t        d d |!      } |       }d"}d# }d$ }d% }i d|d ||      d|r|nd&d	|r|nd&d
|r|nd&d|r|nd&d ||      d ||      d ||	      d ||
      d ||      d ||      d ||      d|r|nd&d|r|nd&d|r|nd&d|r|nd&|r|nd&|r|nd& ||       ||      |r|j                         d'k(  nd | d(}|j                  t        |      |       |j                          |j                          t        d)d*       t        t	        d+            S # t         $ r8} t        d,t#        |        d       t        t	        d|             cY d&} ~ S d&} ~ ww xY w)-zUpdate adventurer   r   r   r   adventure_namer8   
company_idr   r   addresscityr   duration_minutesmax_participantsmin_participantspricecurrency_idr  r3   websiteequipment_providedrequirementssafety_instructions
photo_pathlatitude	longituder   z(Adventure name and company are required.zadmin.edit_adventure)r(  r   Fr   a6  
            UPDATE adventures 
            SET adventure_name = :adventure_name,
                company_id = :company_id,
                phone = :phone,
                email = :email,
                address = :address,
                city = :city,
                country_id = :country_id,
                duration_minutes = :duration_minutes,
                max_participants = :max_participants,
                min_participants = :min_participants,
                price = :price,
                currency_id = :currency_id,
                beach_place_id = :beach_place_id,
                description = :description,
                website = :website,
                equipment_provided = :equipment_provided,
                requirements = :requirements,
                safety_instructions = :safety_instructions,
                photo_path = :photo_path,
                latitude = :latitude,
                longitude = :longitude,
                is_active = :is_active,
                updated_at = NOW()
            WHERE adventure_id = :adventure_id
        c                 >    | r	 t        |       S y # t        $ r Y y w xY wN)r   
ValueErrorvalues    r;   safe_intz"update_adventure.<locals>.safe_int  s-     u:%  "      
 	c                 >    | r	 t        |       S y # t        $ r Y y w xY wr=  )r   r>  r?  s    r;   
safe_floatz$update_adventure.<locals>.safe_float  s-      <'  "   rB  c                 R    | r	 dd l }|j                  |       S y # t        $ r Y y w xY w)Nr   )uuidr   r>  )r@  rF  s     r;   	safe_uuidz#update_adventure.<locals>.safe_uuid  s5     99U++  "   s    	&&Non)r8  r9  r:  r;  r   r(  zAdventure updated successfully.r   r%  zError updating adventure: )r
   r9   r   r   r   r   r   r   r   r   r   lowerrF   r   commitrJ   rH   rT   )!r(  r,  r-  r   r   r.  r/  r   r0  r1  r2  r3  r4  r  r3   r5  r6  r7  r8  r9  r:  r;  r   r   rV   rW   rU   update_queryrA  rD  rG  r   rZ   s!                                    r;   update_adventurerL    s)    ;;z"NPWX 3455~T ))*:B?EEG\\%%lB7==?
  "-335  "-335,,""9b1779||+113\\%%lB7==?
"<<++,>CIIK"<<++,>CIIK"<<++,>CIIK  "-335ll&&}b9??A ))*:B?EEGll&&}b9??A,,""9b1779$\\--.BBGMMO||'';AAC%ll../DbIOOQ\\%%lB7==?
<<##J399;LL$$["5;;=	LL$$["5;;=	 Z<gFG$:VWW $N3|,#uFS^8			
n
)J/
 eU
 eU	

 'wt
 DDd
 (:.
 )9 :
 )9 :
 )9 :
 Z&
 8K0
 i7
 +;4
 'wt
  !8J"4PT!
" LLd#
$ ;N#6SW(2*"8,#I.6?*d2U(/
4 	

4%v.
		

/; 2344 T*3q6(3W= 6\RSSTs%   PV EV 	W -WWWz"/admin/companies/edit/<company_id>c           	      p   t        j                  d      s t        dd       t        t	        d            S d}	 t
        d   }t        |      }t        dd|      } |       }d	dl}d	dl	}|j                  j                  |j                  j                  |j                  j                  |j                  j                  t                                 d	d
lm} d	dlm} |j'                  |      j)                  |j*                  | k(        j-                         }	|	s4t        dd       t        t	        d            |r	 |j/                          S S |j'                  |      j1                  |j2                        j5                         }
t7        d|	|
      |r	 |j/                          S S #  Y S xY w#  Y S xY w# t8        $ rS}t;        d|        t        dd       t        t	        d            cY d}~|r	 |j/                          S #  Y S xY wS d}~ww xY w# |r	 |j/                          w #  Y w xY ww xY w)zEdit companyr   r   r   r   Nr   Fr   r   r   r   zCompany not found.zadmin.companieszadmin/edit_company.html)rj   r   zError fetching company data: z.An error occurred while fetching company data.)r
   r9   r   r   r   r   r   r   r   r   r   rL   r  r  r  r  r   r  r   r  r	  r-  r  rJ   r  r   r  r   rH   rI   )r-  rU   r   rV   rW   r   r   r   r   rj   r   rZ   s               r;   edit_companyrN    s    ;;z"NPWX 3455	B##N3|,#uFS^ 	8Q(RST.+ ((7#**7+=+=+KLRRT&0G$567 
  HHW%..w/C/CDHHJ	8%,'02 
   4-aS12>H 1233
	 4
 
	 ss   DF9 ?F+AF9 F2+F/2F69	H-H/H0H 7HHHH H5H-,H5-H1/H5z/api/beach-photos/<beach_id>c                 	   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }dt        j                  vrt        ddi      dfS t        j                  j                  d      }g }|j                         5 }|j                  t        d      d| i      j                         }|r|d   dkD  nd}|j                  t        d      d| i      j                         }	|	r|	d   dz   nd}
t        |      D ]E  \  }}|j                   s|j                   dk7  s$	 t#        |j                         }ddl}d|v r#|j'                  dd      d   j)                         nd}|j+                         j,                   d| }t        j.                  j1                  t        j.                  j1                  t        j.                  j1                  t        j.                  j3                  t4                                }t        j.                  j7                  |d d!d"      }t	        j8                  |d#$       t;        d%|        t        j.                  j7                  ||      }t;        d&|        |j=                  |       t        j.                  j?                  |      r2t        j.                  jA                  |      }t;        d'| d(| d)       ntC        d*|       |dk(  xr | }|j                  t        d+      | d,| ||
|z   d-      }|j                         }|r|d   nd}|jE                  |d,| |d.       H |jI                          ddd       t        d#tK        |       d2|d3      S # tB        $ r>}t;        d/|        t        dd0tG        |       i      d1fcY d}~c cddd       S d}~ww xY w# 1 sw Y   nxY w# tB        $ r'}t;        d4|        t        dd5i      d1fcY d}~S d}~ww xY w)6zUpload photos for a beach placer   r   Unauthorized  DATABASE_PASSWORDAdminPassword123!postgresql://DATABASE_USERpostgres:@DATABASE_HOST	localhostDATABASE_PORT5432/DATABASE_NAME	bookbeachbeach_photosNo photos uploaded  z
                SELECT COUNT(*) as count FROM beach_places_photos 
                WHERE beach_place_id = :beach_id AND photo_primary = true
            r  r   Fz
                SELECT COALESCE(MAX(sort_order), -1) as max_sort 
                FROM beach_places_photos 
                WHERE beach_place_id = :beach_id
            rs   r8   N.jpgstaticuploadsr!   Texist_okUpload directory: Saving file to: File saved successfully:  ( bytes)File was not saved: aV  
                            INSERT INTO beach_places_photos (
                                beach_place_id, photo_path, photo_primary, sort_order
                            ) VALUES (
                                :beach_id, :photo_path, :is_primary, :sort_order
                            ) RETURNING photo_id
                        z/static/uploads/beaches/)r  r9  
is_primary
sort_orderphoto_idr9  ro  Error uploading photo: Failed to upload photo:    photo(s) uploaded successfullyr   messager  Error in photo upload: Failed to upload photos&r
   r9   r	   r   r   getenvr   r   r   filesgetlistconnectrF   r   rG   	enumeratefilenamer   rF  rsplitrI  uuid4hexr   r  r  r  r   makedirsrI   saveexistsgetsizerH   rL   rT   rJ  r   )r  database_passworddatabase_urlrV   r  uploaded_photosrU   existing_primaryhas_primarymax_sortnext_sort_orderiphotor  rF  file_extunique_filenamebackend_dir
upload_dir	file_path	file_sizero  rX   
result_rowrr  photo_errorrZ   s                              r;   upload_beach_photosr  >  s   gB{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,.G%9:;S@@&&~6^^ N	!zz$ 0 + x( * +3(* 
 6F*1-15K zz$ ( # x(	* +3(*	  2:hqkAoqO%f- :f5>>enn&:8f#25>>#B#ILPX8??3#:1#=#C#C#E^c-1ZZ\-=-=,>az*J ')ggoobggoobggooVXV]V]VeVefnVoFp6q&r%'WW\\+xT]%^
 J> 2:,?@ %'GGLL_$M	 0<= 

9- 77>>)4(*	(BI!$=i[9+U\"]^"+.B9+,N"OO '(1f&@[
 "$D 2 - )1,D_DU*V*4*9A*=	" &,__%6
4>:a=D'..(0,D_DU*V*40 e:fx IIK]N	` o.//NO%
  	 % f 7}EF&3KCP[L\K]1^'_`beeeYN	 N	TfUN	 N	l  B's+,!:;<cAABs   #Q B+Q 1Q BQQ"H!O9Q"Q 9	Q (P;*Q +Q1	Q ;Q  QQQ 	Q?Q:4Q?:Q?z&/api/restaurant-photos/<restaurant_id>c                  	   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }dt        j                  vrt        ddi      dfS t        j                  j                  d      }g }|j                         5 }|j                  t        d      d| i      j                         }|r|d   dkD  nd}|j                  t        d      d| i      j                         }	|	r|	d   dz   nd}
t        |      D ]C  \  }}|j                   s|j                   dk7  s$	 t#        |j                         }ddl}d|v r#|j'                  dd      d   j)                         nd}|j+                         j,                   d| }t        j.                  j1                  t        j.                  j1                  t        j.                  j1                  t        j.                  j3                  t4                                }t        j.                  j7                  |d d!d      }t	        j8                  |d"#       t;        d$|        t        j.                  j7                  ||      }t;        d%|        |j=                  |       t        j.                  j?                  |      r2t        j.                  jA                  |      }t;        d&| d'| d(       ntC        d)|       |dk(  xr | }|j                  t        d*      | d+| |d,      }|j                         }|r|d   nd}|r|jE                  |d+| |d-       F |jI                          ddd       t        d"tK        |       d1|d2      S # tB        $ r>}t;        d.|        t        dd/tG        |       i      d0fcY d}~c cddd       S d}~ww xY w# 1 sw Y   nxY w# tB        $ r'}t;        d3|        t        dd4i      d0fcY d}~S d}~ww xY w)5zUpload photos for a restaurantr   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  restaurant_photosra  rb  z
                SELECT COUNT(*) as count FROM restaurant_photos 
                WHERE restaurant_id = :restaurant_id AND is_primary = true
            r
  r   Fz
                SELECT COALESCE(MAX(photo_id), 0) as max_sort 
                FROM restaurant_photos 
                WHERE restaurant_id = :restaurant_id
            rs   r8   Nrc  rd  re  rf  Trg  ri  rj  rk  rl  rm  rn  a<  
                            INSERT INTO restaurant_photos (
                                restaurant_id, photo_path, is_primary
                            ) VALUES (
                                :restaurant_id, :photo_path, :is_primary
                            ) RETURNING photo_id
                        z"/static/uploads/restaurant_photos/)r
  r9  ro  rq  rs  rt  ru  rv  rw  ry  rz  r{  )r
  r  r  rV   r  r  rU   r  r  r  r  r  r  r  rF  r  r  r  r  r  r  ro  rX   r  rr  r  rZ   s                              r;   upload_restaurant_photosr    s   gB{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,gmm3G%9:;S@@&&':;^^ N	!zz$ 0 + #M2 4 5=HJ 
 6F*1-15K zz$ ( # #M2	4 5=HJ	  2:hqkAoqO%f- :f5>>enn&:8f#25>>#B#ILPX8??3#:1#=#C#C#E^c-1ZZ\-=-=,>az*J ')ggoobggoobggooVXV]V]VeVefnVoFp6q&r%'WW\\+xTg%h
 J> 2:,?@ %'GGLL_$M	 0<= 

9- 77>>)4(*	(BI!$=i[9+U\"]^"+.B9+,N"OO '(1f&@[
 "$D 2 - .;,NN_*`*4
" &,__%6
4>:a=D#+22,40RSbRc.d.84 e:fx IIK]N	` o.//NO%
  	 % f 7}EF&3KCP[L\K]1^'_`beeeYN	 N	TfUN	 N	l  B's+,!:;<cAABs   #Q B+Q 1Q BQQ"HO7Q"Q 7	P> (P9(P>)Q/	Q 9P>>QQ
Q 	Q=Q82Q=8Q=z/api/market-photos/<market_id>c                    	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }dt        j                  vrt        ddi      dfS t        j                  j                  d      }g }|j                         5 }|j                  t        d      d| i      j                         }|j                  dkD  }|j                  t        d      d| i      j                         }	|	j                   dz   }
t#        |      D ].  \  }}|j$                  dk7  s	 t'        |j$                        }ddl}d|v r#|j+                  dd      d   j-                         nd}|j/                         j0                   d| }t        j2                  j5                  t        j2                  j5                  t        j2                  j5                  t        j2                  j7                  t8                                }t        j2                  j;                  |dd d!      }t	        j<                  |d"#       t?        d$|        t        j2                  j;                  ||      }t?        d%|        |jA                  |       t        j2                  jC                  |      r2t        j2                  jE                  |      }t?        d&| d'| d(       ntG        d)|       |dk(  xr | }|j                  t        d*      | d+| |d,      }|j                         d   }|jI                  |d+| |d-       1 |jM                          ddd       t        d"tO        |       d1|d2      S # tF        $ r>}t?        d.|        t        dd/tK        |       i      d0fcY d}~c cddd       S d}~ww xY w# 1 sw Y   nxY w# tF        $ r'}t?        d3|        t        dd4i      d0fcY d}~S d}~ww xY w)5zUpload photos for a marketr   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  market_photosra  rb  z
                SELECT COUNT(*) as count FROM market_photos 
                WHERE market_id = :market_id AND is_primary = true
            r  r   z
                SELECT COALESCE(MAX(photo_id), 0) as max_sort 
                FROM market_photos 
                WHERE market_id = :market_id
            rs   r8   Nrc  rd  re  rf  r#   Trg  ri  rj  rk  rl  rm  rn  a0  
                            INSERT INTO market_photos (
                                market_id, photo_path, is_primary
                            ) VALUES (
                                :market_id, :photo_path, :is_primary
                            ) RETURNING photo_id
                        z/static/uploads/markets/)r  r9  ro  rq  rs  rt  ru  rv  rw  ry  rz  (r
   r9   r	   r   r   r|  r   r   r   r}  r~  r  rF   r   rG   countr  r  r  r   rF  r  rI  r  r  r   r  r  r  r   r  rI   r  r  r  rH   rL   rT   rJ  r   )r  r  r  rV   r  r  rU   r  r  r  r  r  r  r  rF  r  r  r  r  r  r  ro  rX   rr  r  rZ   s                             r;   upload_market_photosr    s   eB{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,'--/G%9:;S@@&&7^^ L	!zz$ 0 + 	* , -5HJ 
 +0014K zz$ ( # 	*	, -5HJ	  '//!3O%f- 8f5>>R'6f#25>>#B#ILPX8??3#:1#=#C#C#E^c-1ZZ\-=-=,>az*J ')ggoobggoobggooVXV]V]VeVefnVoFp6q&r%'WW\\+xT]%^
 J> 2:,?@ %'GGLL_$M	 0<= 

9- 77>>)4(*	(BI!$=i[9+U\"]^"+.B9+,N"OO '(1f&@[
 "$D 2 - *3,D_DU*V*4
" $*??#4Q#7'..(0,D_DU*V*40 a8ft IIKYL	\ o.//NO%
  	 % f 7}EF&3KCP[L\K]1^'_`beeeUL	 L	PfQL	 L	h  B's+,!:;<cAABy   #P> B+P> 1P> BP2HO(2P2"P> (	P/1(P*P/P2 	P> *P//P22P;7P> >	Q.Q)#Q.)Q.z$/api/adventure-photos/<adventure_id>c                    	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }dt        j                  vrt        ddi      dfS t        j                  j                  d      }g }|j                         5 }|j                  t        d      d| i      j                         }|j                  dkD  }|j                  t        d      d| i      j                         }	|	j                   dz   }
t#        |      D ].  \  }}|j$                  dk7  s	 t'        |j$                        }ddl}d|v r#|j+                  dd      d   j-                         nd}|j/                         j0                   d| }t        j2                  j5                  t        j2                  j5                  t        j2                  j5                  t        j2                  j7                  t8                                }t        j2                  j;                  |dd d!      }t	        j<                  |d"#       t?        d$|        t        j2                  j;                  ||      }t?        d%|        |jA                  |       t        j2                  jC                  |      r2t        j2                  jE                  |      }t?        d&| d'| d(       ntG        d)|       |dk(  xr | }|j                  t        d*      | d+| |d,      }|j                         d   }|jI                  |d+| |d-       1 |jM                          ddd       t        d"tO        |       d1|d2      S # tF        $ r>}t?        d.|        t        dd/tK        |       i      d0fcY d}~c cddd       S d}~ww xY w# 1 sw Y   nxY w# tF        $ r'}t?        d3|        t        dd4i      d0fcY d}~S d}~ww xY w)5zUpload photos for an adventurer   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  adventure_photosra  rb  z
                SELECT COUNT(*) as count FROM adventure_photos 
                WHERE adventure_id = :adventure_id AND is_primary = true
            r(  r   z
                SELECT COALESCE(MAX(photo_id), 0) as max_sort 
                FROM adventure_photos 
                WHERE adventure_id = :adventure_id
            rs   r8   Nrc  rd  re  rf  r$   Trg  ri  rj  rk  rl  rm  rn  a9  
                            INSERT INTO adventure_photos (
                                adventure_id, photo_path, is_primary
                            ) VALUES (
                                :adventure_id, :photo_path, :is_primary
                            ) RETURNING photo_id
                        z/static/uploads/adventures/)r(  r9  ro  rq  rs  rt  ru  rv  rw  ry  rz  r  )r(  r  r  rV   r  r  rU   r  r  r  r  r  r  r  rF  r  r  r  r  r  r  ro  rX   rr  r  rZ   s                             r;   upload_adventure_photosr    s   eB{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,W]]2G%9:;S@@&&'9:^^ L	!zz$ 0 + "<0 2 3;(* 
 +0014K zz$ ( # "<0	2 3;(*	  '//!3O%f- 8f5>>R'6f#25>>#B#ILPX8??3#:1#=#C#C#E^c-1ZZ\-=-=,>az*J ')ggoobggoobggooVXV]V]VeVefnVoFp6q&r%'WW\\+xT`%a
 J> 2:,?@ %'GGLL_$M	 0<= 

9- 77>>)4(*	(BI!$=i[9+U\"]^"+.B9+,N"OO '(1f&@[
 "$D 2 - -9,GGX*Y*4
" $*??#4Q#7'..(0,GGX*Y*40 a8ft IIKYL	\ o.//NO%
  	 % f 7}EF&3KCP[L\K]1^'_`beeeUL	 L	PfQL	 L	h  B's+,!:;<cAABr  z(/api/beach-photos/<photo_id>/set-primaryPUTc                 f   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  }|j                  t        d      d|i       |j                  t        d      d| i       |j                          t        ddd      cddd       S # 1 sw Y   yxY w# t        $ r'}t        d|        t        ddi      d fcY d}~S d}~ww xY w)!z.Set a photo as the primary photo for its beachr   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zx
                SELECT beach_place_id FROM beach_places_photos 
                WHERE photo_id = :photo_id
            rr  Photo not found  Nz
                UPDATE beach_places_photos 
                SET photo_primary = false 
                WHERE beach_place_id = :beach_place_id
            r  z
                UPDATE beach_places_photos 
                SET photo_primary = true 
                WHERE photo_id = :photo_id
            T!Photo set as primary successfullyr   rx   Error setting photo as primary: Failed to set photo as primaryru  )r
   r9   r	   r   r   r|  r   r   r  rF   r   rG   r  rJ  rH   rI   )rr  r  r  rV   rU   photo_resultr  rZ   s           r;   set_beach_photo_primaryr    s)   )I{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	^::d , ' x(* +3(* 
  ):;<cA	^ 	^ *88N JJt   $^4	6 JJt   x(	* IIKt8[\]9	^ 	^ 	^<  I045!ABCSHHIN   #F  BF  <E4=	F  A#E4*	F  4E=9F  =F   	F0	F+%F0+F0z-/api/restaurant-photos/<photo_id>/set-primaryc                 f   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  }|j                  t        d      d|i       |j                  t        d      d| i       |j                          t        ddd      cddd       S # 1 sw Y   yxY w# t        $ r'}t        d|        t        ddi      d fcY d}~S d}~ww xY w)!z3Set a photo as the primary photo for its restaurantr   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zu
                SELECT restaurant_id FROM restaurant_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nz
                UPDATE restaurant_photos 
                SET is_primary = false 
                WHERE restaurant_id = :restaurant_id
            r
  z
                UPDATE restaurant_photos 
                SET is_primary = true 
                WHERE photo_id = :photo_id
            Tr  r  r  r  ru  )r
   r9   r	   r   r   r|  r   r   r  rF   r   rG   r
  rJ  rH   rI   )rr  r  r  rV   rU   r  r
  rZ   s           r;   set_restaurant_photo_primaryr  	  s)   )I{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	^::d , ' x(* +3(* 
  ):;<cA	^ 	^ )66M JJt   #M2	4 JJt   x(	* IIKt8[\]9	^ 	^ 	^<  I045!ABCSHHIr  z)/api/market-photos/<photo_id>/set-primaryc                 f   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  }|j                  t        d      d|i       |j                  t        d      d| i       |j                          t        ddd      cddd       S # 1 sw Y   yxY w# t        $ r'}t        d|        t        ddi      d fcY d}~S d}~ww xY w)!z/Set a photo as the primary photo for its marketr   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zm
                SELECT market_id FROM market_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nz
                UPDATE market_photos 
                SET is_primary = false 
                WHERE market_id = :market_id
            r  z
                UPDATE market_photos 
                SET is_primary = true 
                WHERE photo_id = :photo_id
            Tr  r  r  r  ru  )r
   r9   r	   r   r   r|  r   r   r  rF   r   rG   r  rJ  rH   rI   )rr  r  r  rV   rU   r  r  rZ   s           r;   set_market_photo_primaryr  L	  s)   )I{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	^::d , ' x(* +3(* 
  ):;<cA	^ 	^ %..I JJt   	*	, JJt   x(	* IIKt8[\]9	^ 	^ 	^<  I045!ABCSHHIr  z,/api/adventure-photos/<photo_id>/set-primaryc                 f   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  }|j                  t        d      d|i       |j                  t        d      d| i       |j                          t        ddd      cddd       S # 1 sw Y   yxY w# t        $ r'}t        d|        t        ddi      d fcY d}~S d}~ww xY w)!z2Set a photo as the primary photo for its adventurer   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zs
                SELECT adventure_id FROM adventure_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nz
                UPDATE adventure_photos 
                SET is_primary = false 
                WHERE adventure_id = :adventure_id
            r(  z
                UPDATE adventure_photos 
                SET is_primary = true 
                WHERE photo_id = :photo_id
            Tr  r  r  r  ru  )r
   r9   r	   r   r   r|  r   r   r  rF   r   rG   r(  rJ  rH   rI   )rr  r  r  rV   rU   r  r(  rZ   s           r;   set_adventure_photo_primaryr  {	  s)   )I{{:&G^45s::(,,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	^::d , ' x(* +3(* 
  ):;<cA	^ 	^ (44L JJt   "<0	2 JJt   x(	* IIKt8[\]9	^ 	^ 	^<  I045!ABCSHHIr  z/api/beach-photos/<photo_id>DELETEc                 4   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  t        d      d| i       |j                          	 |j                  }|j                  d      rt        j                  j!                  t        j                  j#                  t        j                  j#                  t        j                  j#                  t        j                  j%                  t&                                |dd       }t        j                  j)                  |      rt	        j*                  |       t        ddi      cddd       S # t,        $ r}t/        d|        Y d}~2d}~ww xY w# 1 sw Y   yxY w# t,        $ r'}	t/        d|	        t        ddi      d fcY d}	~	S d}	~	ww xY w)!zDelete a beach photor   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zt
                SELECT photo_path FROM beach_places_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nzi
                DELETE FROM beach_places_photos 
                WHERE photo_id = :photo_id
            /static/rs   Error deleting photo file: r   TzError deleting beach photo: Failed to delete photoru  r
   r9   r	   r   r   r|  r   r   r  rF   r   rG   rJ  r9  
startswithr   r   r  r  r  r  removerH   rI   
rr  r  r  rV   rU   r  r9  r  
file_errorrZ   s
             r;   delete_beach_photor  	  s   *A{{:&G^45s:: ),,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	.::d , ' x(* +3(* 
  ):;<cA	. 	. JJt   x(*
 IIKB)44
((4 "RWW__RWW__RWW__]_]d]d]l]lmu]vMw=x-y  |F  GH  GI  |J  !KIww~~i0		), It,-9	. 	.2  B3J<@AAB3	. 	.<  A,QC01!9:;S@@Ax   #I' BI' <I=	I' -I5C,H7!I-	I' 7	I IIIII$ I' $I' '	J0JJJz!/api/restaurant-photos/<photo_id>c                 4   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  t        d      d| i       |j                          	 |j                  }|j                  d      rt        j                  j!                  t        j                  j#                  t        j                  j#                  t        j                  j#                  t        j                  j%                  t&                                |dd       }t        j                  j)                  |      rt	        j*                  |       t        ddi      cddd       S # t,        $ r}t/        d|        Y d}~2d}~ww xY w# 1 sw Y   yxY w# t,        $ r'}	t/        d|	        t        ddi      d fcY d}	~	S d}	~	ww xY w)!zDelete a restaurant photor   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zr
                SELECT photo_path FROM restaurant_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nzg
                DELETE FROM restaurant_photos 
                WHERE photo_id = :photo_id
            r  rs   r  r   Tz!Error deleting restaurant photo: r  ru  r  r  s
             r;   delete_restaurant_photor  	  s   *A{{:&G^45s:: ),,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	.::d , ' x(* +3(* 
  ):;<cA	. 	. JJt   x(*
 IIKB)44
((4 "RWW__RWW__RWW__]_]d]d]l]lmu]vMw=x-y  |F  GH  GI  |J  !KIww~~i0		), It,-9	. 	.2  B3J<@AAB3	. 	.<  A1!56!9:;S@@Ar  z/api/market-photos/<photo_id>c                 4   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  t        d      d| i       |j                          	 |j                  }|j                  d      rt        j                  j!                  t        j                  j#                  t        j                  j#                  t        j                  j#                  t        j                  j%                  t&                                |dd       }t        j                  j)                  |      rt	        j*                  |       t        ddi      cddd       S # t,        $ r}t/        d|        Y d}~2d}~ww xY w# 1 sw Y   yxY w# t,        $ r'}	t/        d|	        t        ddi      d fcY d}	~	S d}	~	ww xY w)!zDelete a market photor   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zn
                SELECT photo_path FROM market_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nzc
                DELETE FROM market_photos 
                WHERE photo_id = :photo_id
            r  rs   r  r   TzError deleting market photo: r  ru  r  r  s
             r;   delete_market_photor  

  s   *A{{:&G^45s:: ),,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	.::d , ' x(* +3(* 
  ):;<cA	. 	. JJt   x(*
 IIKB)44
((4 "RWW__RWW__RWW__]_]d]d]l]lmu]vMw=x-y  |F  GH  GI  |J  !KIww~~i0		), It,-9	. 	.2  B3J<@AAB3	. 	.<  A-aS12!9:;S@@Ar  z /api/adventure-photos/<photo_id>c                 4   	 t        j                  d      st        ddi      dfS t        j                  dd      }dt	        j
                  dd	       d
t        |       dt	        j
                  dd       d
t	        j
                  dd       dt	        j
                  dd       
}t        |      }|j                         5 }|j                  t        d      d| i      j                         }|st        ddi      dfcddd       S |j                  t        d      d| i       |j                          	 |j                  }|j                  d      rt        j                  j!                  t        j                  j#                  t        j                  j#                  t        j                  j#                  t        j                  j%                  t&                                |dd       }t        j                  j)                  |      rt	        j*                  |       t        ddi      cddd       S # t,        $ r}t/        d|        Y d}~2d}~ww xY w# 1 sw Y   yxY w# t,        $ r'}	t/        d|	        t        ddi      d fcY d}	~	S d}	~	ww xY w)!zDelete an adventure photor   r   rP  rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r^  r_  zq
                SELECT photo_path FROM adventure_photos 
                WHERE photo_id = :photo_id
            rr  r  r  Nzf
                DELETE FROM adventure_photos 
                WHERE photo_id = :photo_id
            r  rs   r  r   Tz Error deleting adventure photo: r  ru  r  r  s
             r;   delete_adventure_photor  :
  s   *A{{:&G^45s:: ),,-@BUV&ryy*'M&NaPZ[lPmOnnoprpypy  {J  LW  qX  pY  YZ  []  [d  [d  et  v|  [}  Z~  ~  @B  @I  @I  JY  [f  @g  h  i|,^^ 	.::d , ' x(* +3(* 
  ):;<cA	. 	. JJt   x(*
 IIKB)44
((4 "RWW__RWW__RWW__]_]d]d]l]lmu]vMw=x-y  |F  GH  GI  |J  !KIww~~i0		), It,-9	. 	.2  B3J<@AAB3	. 	.<  A045!9:;S@@Ar  z/beaches/<beach_id>/designc                 2   t        j                  d      s t        dd       t        t	        d            S 	 t        d|        S # t
        $ rH}dt        |       }t        d|        t        |d       t        t	        d| 	            cY d
}~S d
}~ww xY w)zFull screen beach design pager   r   r   r   z(/static/BeachDesign/index.html?beach_id=zError loading beach design: r  r  r  N)r
   r9   r   r   r   rH   rT   rI   )r  rZ   r  s      r;   beach_designr  i
  s    
 ;;z"NPWX 3455	HB8*MNN H23q6(;	$YK01i! 2XFGGHs   A 	B=BBB)E__doc__flaskr   r   r   r   r   r   r	   r
   flask_loginr   r   werkzeug.securityr   r   werkzeug.utilsr   
sqlalchemyr   r   sqlalchemy.ormr   rF  r   urllib.parser   r   r   r   rL   r  r  r  configr   __name__admin_bprouterl   r4   r   r%   r   r   r&   r!   r"   r  r  r#   r$   r!  r*  rL  rN  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r=   r;   <module>r     s   b a a 4 I * * '  # 	 
 0I JK L  Wh'	gW gWRB 
80) 90)d 
Q6  Q6f 
!"	2 #	2 
 !vG "vGp 
"#r+ $r+h 
 !i6 "i6V 
$%i6 &i6V 
9:8 ;8t 
013 23j 
 !i6 "i6V 
#$j6 %j6X 
12> 3>@ 
7%I< J<| 
9F8LET METN 
4ugF+ G+` 
.AiB BiBX 
86(KiB LiBX 
06(CgB DgBT 
6IgB JgBT 
:UGL+I M+I\ 
?%Q+I R+I\ 
;eWM+I N+I\ 
>P+I Q+I\ 
.
C,A D,A^ 
3hZH,A I,A^ 
/(D,A E,A^ 
2XJG,A H,A\ 
,ug>H  ?Hr=   