package com.aistudio.bonjuteri.jwlry import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.BackHandler import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.aistudio.bonjuteri.jwlry.data.AddressRepository import com.aistudio.bonjuteri.jwlry.data.AdminDashboardMetrics import com.aistudio.bonjuteri.jwlry.data.AdminDashboardRepository import com.aistudio.bonjuteri.jwlry.data.AuthRepository import com.aistudio.bonjuteri.jwlry.data.BannerRepository import com.aistudio.bonjuteri.jwlry.data.CartRepository import com.aistudio.bonjuteri.jwlry.data.CategoryRepository import com.aistudio.bonjuteri.jwlry.data.FavoriteRepository import com.aistudio.bonjuteri.jwlry.data.OrderRepository import com.aistudio.bonjuteri.jwlry.data.ProductRepository import com.aistudio.bonjuteri.jwlry.model.Address import com.aistudio.bonjuteri.jwlry.model.Category import com.aistudio.bonjuteri.jwlry.model.Order import com.aistudio.bonjuteri.jwlry.model.OrderStatus import com.aistudio.bonjuteri.jwlry.model.PaymentStatus import com.aistudio.bonjuteri.jwlry.model.Product import com.aistudio.bonjuteri.jwlry.model.UserProfile import com.aistudio.bonjuteri.jwlry.ui.components.BonjuteriBottomBar import com.aistudio.bonjuteri.jwlry.ui.components.BonjuteriTopBar import com.aistudio.bonjuteri.jwlry.ui.components.BottomNavDestination import com.aistudio.bonjuteri.jwlry.ui.screens.AddressesScreen import com.aistudio.bonjuteri.jwlry.ui.screens.AuthScreen import com.aistudio.bonjuteri.jwlry.ui.screens.CartScreen import com.aistudio.bonjuteri.jwlry.ui.screens.CategoriesScreen import com.aistudio.bonjuteri.jwlry.ui.screens.CheckoutScreen import com.aistudio.bonjuteri.jwlry.ui.screens.FavoritesScreen import com.aistudio.bonjuteri.jwlry.ui.screens.HomeScreen import com.aistudio.bonjuteri.jwlry.ui.screens.OrdersScreen import com.aistudio.bonjuteri.jwlry.ui.screens.ProductDetailScreen import com.aistudio.bonjuteri.jwlry.ui.screens.ProfileScreen import com.aistudio.bonjuteri.jwlry.ui.screens.admin.AdminBannerScreen import com.aistudio.bonjuteri.jwlry.ui.screens.admin.AdminCategoryScreen import com.aistudio.bonjuteri.jwlry.ui.screens.admin.AdminDashboardScreen import com.aistudio.bonjuteri.jwlry.ui.screens.admin.AdminOrderScreen import com.aistudio.bonjuteri.jwlry.ui.screens.admin.AdminProductScreen import com.aistudio.bonjuteri.jwlry.ui.screens.admin.AdminSection import com.aistudio.bonjuteri.jwlry.ui.theme.BonjuteriTheme import com.aistudio.bonjuteri.jwlry.ui.theme.GoldPrimary import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { BonjuteriTheme { BonjuteriApp() } } } } @Composable fun BonjuteriApp() { val context = LocalContext.current val scope = rememberCoroutineScope() val snackbarHostState = remember { SnackbarHostState() } // Repositories val authRepo = remember { AuthRepository.getInstance(context) } val productRepo = remember { ProductRepository.getInstance(context) } val categoryRepo = remember { CategoryRepository.getInstance(context) } val bannerRepo = remember { BannerRepository.getInstance(context) } val cartRepo = remember { CartRepository.getInstance(context) } val favoriteRepo = remember { FavoriteRepository.getInstance(context) } val addressRepo = remember { AddressRepository.getInstance(context) } val orderRepo = remember { OrderRepository.getInstance(context) } val dashboardRepo = remember { AdminDashboardRepository.getInstance(context) } // Auth state observation val userProfile by authRepo.userProfileState.collectAsStateWithLifecycle() val isAuthReady by authRepo.isAuthReady.collectAsStateWithLifecycle() if (!isAuthReady) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator(color = GoldPrimary) } return } if (userProfile == null) { // Unauthenticated User Gate AuthScreen( onSignInWithEmail = { email, password -> authRepo.signInWithEmail(email, password) }, onSignUpWithEmail = { fName, lName, email, pass -> authRepo.signUpWithEmail(fName, lName, email, pass) }, onSignInWithCredential = { cred -> authRepo.signInWithCredential(cred) }, onSendPasswordReset = { email -> authRepo.sendPasswordReset(email) }, onAuthSuccess = { /* profile updated automatically */ }, snackbarHostState = snackbarHostState ) } else { // Authenticated Session MainShoppingContent( currentUser = userProfile!!, productRepo = productRepo, categoryRepo = categoryRepo, bannerRepo = bannerRepo, cartRepo = cartRepo, favoriteRepo = favoriteRepo, addressRepo = addressRepo, orderRepo = orderRepo, dashboardRepo = dashboardRepo, onSignOut = { authRepo.signOut() }, snackbarHostState = snackbarHostState ) } } @Composable private fun MainShoppingContent( currentUser: UserProfile, productRepo: ProductRepository, categoryRepo: CategoryRepository, bannerRepo: BannerRepository, cartRepo: CartRepository, favoriteRepo: FavoriteRepository, addressRepo: AddressRepository, orderRepo: OrderRepository, dashboardRepo: AdminDashboardRepository, onSignOut: () -> Unit, snackbarHostState: SnackbarHostState ) { val scope = rememberCoroutineScope() // Navigation and screen states var currentNavDestination by remember { mutableStateOf(BottomNavDestination.HOME) } var selectedProductDetail by remember { mutableStateOf(null) } var isCheckingOut by remember { mutableStateOf(false) } var isViewingOrders by remember { mutableStateOf(false) } var isViewingAddresses by remember { mutableStateOf(false) } var currentAdminSection by remember { mutableStateOf(null) } var searchQuery by remember { mutableStateOf("") } // Live Data observations val products by productRepo.observeProducts(onlyActive = true).collectAsStateWithLifecycle(initialValue = emptyList()) val allAdminProducts by productRepo.observeProducts(onlyActive = false).collectAsStateWithLifecycle(initialValue = emptyList()) val categories by categoryRepo.observeCategories().collectAsStateWithLifecycle(initialValue = emptyList()) val banners by bannerRepo.observeBanners().collectAsStateWithLifecycle(initialValue = emptyList()) val cartItems by cartRepo.observeCart().collectAsStateWithLifecycle(initialValue = emptyList()) val favoriteIds by favoriteRepo.observeFavoriteProductIds().collectAsStateWithLifecycle(initialValue = emptySet()) val userAddresses by addressRepo.observeAddresses().collectAsStateWithLifecycle(initialValue = emptyList()) val userOrders by orderRepo.observeUserOrders().collectAsStateWithLifecycle(initialValue = emptyList()) val allAdminOrders by (if (currentUser.userRole.isPrivileged) { orderRepo.observeAllOrders() } else { kotlinx.coroutines.flow.flowOf(emptyList()) }).collectAsStateWithLifecycle(initialValue = emptyList()) var adminMetrics by remember { mutableStateOf(AdminDashboardMetrics()) } LaunchedEffect(currentAdminSection, allAdminProducts, allAdminOrders) { if (currentUser.userRole.isPrivileged) { adminMetrics = dashboardRepo.getMetrics() } } // Back handling BackHandler(enabled = true) { when { currentAdminSection != null && currentAdminSection != AdminSection.DASHBOARD -> { currentAdminSection = AdminSection.DASHBOARD } currentAdminSection == AdminSection.DASHBOARD -> { currentAdminSection = null } isCheckingOut -> { isCheckingOut = false } selectedProductDetail != null -> { selectedProductDetail = null } isViewingOrders -> { isViewingOrders = false } isViewingAddresses -> { isViewingAddresses = false } currentNavDestination != BottomNavDestination.HOME -> { currentNavDestination = BottomNavDestination.HOME } } } // 1. Admin Section Screens val adminSection = currentAdminSection if (adminSection != null && currentUser.userRole.isPrivileged) { when (adminSection) { AdminSection.DASHBOARD -> { AdminDashboardScreen( metrics = adminMetrics, onNavigateSection = { currentAdminSection = it }, onBackClick = { currentAdminSection = null } ) } AdminSection.PRODUCTS -> { AdminProductScreen( products = allAdminProducts, categories = categories, onAddProduct = { title, desc, sku, cat, price, oldPrice, stock, img, isActive, isNew, isBest, isFeat -> productRepo.addProduct(title, desc, sku, cat, price, oldPrice, stock, img, isActive, isNew, isBest, isFeat) }, onUpdateProduct = { productRepo.updateProduct(it) }, onDeleteProduct = { productRepo.deleteProduct(it) }, onBackClick = { currentAdminSection = AdminSection.DASHBOARD }, snackbarHostState = snackbarHostState ) } AdminSection.ORDERS -> { AdminOrderScreen( orders = allAdminOrders, onUpdateOrderStatus = { id, st -> orderRepo.updateOrderStatus(id, st) }, onUpdateCargoInfo = { id, comp, track -> orderRepo.updateCargoInfo(id, comp, track) }, onUpdatePaymentStatus = { id, pay -> orderRepo.updatePaymentStatus(id, pay) }, onBackClick = { currentAdminSection = AdminSection.DASHBOARD }, snackbarHostState = snackbarHostState ) } AdminSection.CATEGORIES -> { AdminCategoryScreen( categories = categories, onAddCategory = { name, img, ord -> categoryRepo.addCategory(name, img, ord) }, onUpdateCategory = { categoryRepo.updateCategory(it) }, onDeleteCategory = { categoryRepo.deleteCategory(it) }, onBackClick = { currentAdminSection = AdminSection.DASHBOARD }, snackbarHostState = snackbarHostState ) } AdminSection.BANNERS -> { AdminBannerScreen( banners = banners, onAddBanner = { t, sub, img, l, ord -> bannerRepo.addBanner(t, sub, img, l, ord) }, onUpdateBanner = { bannerRepo.updateBanner(it) }, onDeleteBanner = { bannerRepo.deleteBanner(it) }, onBackClick = { currentAdminSection = AdminSection.DASHBOARD }, snackbarHostState = snackbarHostState ) } } return } // 2. Checkout Screen if (isCheckingOut) { CheckoutScreen( cartItems = cartItems, addresses = userAddresses, onBackClick = { isCheckingOut = false }, onSaveNewAddress = { addressRepo.saveAddress(it) }, onCreateOrder = { addr, method -> orderRepo.createOrder(cartItems, addr, method) }, onOrderSuccess = { createdOrder -> isCheckingOut = false currentNavDestination = BottomNavDestination.PROFILE isViewingOrders = true scope.launch { snackbarHostState.showSnackbar("Siparişiniz başarıyla alındı! Sipariş No: ${createdOrder.orderNumber}") } } ) return } // 3. Product Detail Screen val productDetail = selectedProductDetail if (productDetail != null) { ProductDetailScreen( product = productDetail, isFavorite = favoriteIds.contains(productDetail.id), onBackClick = { selectedProductDetail = null }, onFavoriteToggle = { scope.launch { favoriteRepo.toggleFavorite(productDetail.id) } }, onAddToCart = { qty -> scope.launch { cartRepo.addToCart(productDetail, qty) } }, snackbarHostState = snackbarHostState ) return } // 4. Sub-Screens: Orders or Addresses if (isViewingOrders) { OrdersScreen( orders = userOrders, onBackClick = { isViewingOrders = false } ) return } if (isViewingAddresses) { AddressesScreen( addresses = userAddresses, onSaveAddress = { addressRepo.saveAddress(it) }, onDeleteAddress = { addressRepo.deleteAddress(it) }, onBackClick = { isViewingAddresses = false }, snackbarHostState = snackbarHostState ) return } // 5. Main Shop Scaffold (TopBar, Content, BottomBar) Scaffold( topBar = { BonjuteriTopBar( searchQuery = searchQuery, onSearchQueryChange = { searchQuery = it }, cartItemCount = cartItems.sumOf { it.quantity }.toInt(), onCartClicked = { currentNavDestination = BottomNavDestination.CART }, showSearch = currentNavDestination == BottomNavDestination.HOME ) }, bottomBar = { BonjuteriBottomBar( currentDestination = currentNavDestination, onDestinationSelected = { dest -> currentNavDestination = dest if (dest != BottomNavDestination.HOME) { searchQuery = "" } }, cartCount = cartItems.sumOf { it.quantity }.toInt(), favoritesCount = favoriteIds.size ) }, snackbarHost = { SnackbarHost(snackbarHostState) } ) { innerPadding -> Box( modifier = Modifier .fillMaxSize() .padding(innerPadding) ) { when (currentNavDestination) { BottomNavDestination.HOME -> { HomeScreen( products = products, categories = categories, banners = banners, favoriteProductIds = favoriteIds, searchQuery = searchQuery, isLoading = false, onProductClick = { selectedProductDetail = it }, onFavoriteToggle = { scope.launch { favoriteRepo.toggleFavorite(it.id) } }, onAddToCart = { scope.launch { cartRepo.addToCart(it, 1L) } }, onCategoryClick = { /* */ }, snackbarHostState = snackbarHostState ) } BottomNavDestination.CATEGORIES -> { CategoriesScreen( categories = categories, products = products, favoriteProductIds = favoriteIds, onProductClick = { selectedProductDetail = it }, onFavoriteToggle = { scope.launch { favoriteRepo.toggleFavorite(it.id) } }, onAddToCart = { scope.launch { cartRepo.addToCart(it, 1L) } } ) } BottomNavDestination.FAVORITES -> { val favProducts = products.filter { favoriteIds.contains(it.id) } FavoritesScreen( favoriteProducts = favProducts, onProductClick = { selectedProductDetail = it }, onFavoriteToggle = { scope.launch { favoriteRepo.toggleFavorite(it.id) } }, onAddToCart = { scope.launch { cartRepo.addToCart(it, 1L) } }, onStartShoppingClick = { currentNavDestination = BottomNavDestination.HOME } ) } BottomNavDestination.CART -> { CartScreen( cartItems = cartItems, onUpdateQuantity = { id, qty -> scope.launch { cartRepo.updateQuantity(id, qty) } }, onRemoveItem = { id -> scope.launch { cartRepo.removeFromCart(id) } }, onCheckoutClick = { isCheckingOut = true }, onStartShoppingClick = { currentNavDestination = BottomNavDestination.HOME } ) } BottomNavDestination.PROFILE -> { ProfileScreen( userProfile = currentUser, orderCount = userOrders.size, addressCount = userAddresses.size, onOrdersClick = { isViewingOrders = true }, onAddressesClick = { isViewingAddresses = true }, onAdminPanelClick = { currentAdminSection = AdminSection.DASHBOARD }, onSignOutClick = onSignOut ) } } } } }