<?php

namespace App\Controllers;

use App\Models\ProductModel;
use App\Models\ProductImageModel;
use App\Models\BrandModel;
use App\Models\OfferModel;
use App\Models\OrderModel;
use App\Models\NotificationModel;
use App\Models\OrderStatusHistoryModel;
use App\Models\UserModel;
use App\Models\ReviewModel;

class Seller extends BaseController
{
    protected $productModel;
    protected $imageModel;
    protected $brandModel;
    protected $offerModel;
    protected $orderModel;
    protected $notificationModel;

    public function __construct()
    {
        $this->productModel = new ProductModel();
        $this->imageModel = new ProductImageModel();
        $this->brandModel = new BrandModel();
        $this->offerModel = new OfferModel();
        $this->orderModel = new OrderModel();
        $this->notificationModel = new NotificationModel();
    }

    public function dashboard()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);
        
        $data = [
            'user' => $user,
            'products' => $this->productModel->getSellerProducts($userId),
            'pending_offers' => $this->offerModel->getSellerOffers($userId, 'pending'),
            'active_orders' => $this->orderModel->getSellerOrders($userId, 'confirmed'),
            'brands' => $this->brandModel->getSellerBrands($userId),
            'notifications' => $this->notificationModel->getUserNotifications($userId, true),
        ];

        return view('seller/dashboard_new', $data);
    }

    public function uploadProduct()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);
        
        $data = [
            'user' => $user,
            'brands' => $this->brandModel->getSellerBrands($userId),
            'canCreateBrand' => ($user['seller_reliability_score'] ?? 0) >= 25,
        ];

        return view('seller/upload_product_new', $data);
    }

    public function processUpload()
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        helper('price_calculator');
        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        // Check subscription limits (S34, S37)
        $uploadCount = $user['products_uploaded_count'] ?? 0;
        $tier = $user['subscription_tier'] ?? 'free';
        $limits = getSubscriptionLimits($tier);

        if ($uploadCount >= $limits['max_products']) {
            return $this->response->setJSON([
                'success' => false,
                'message' => "Upload limit reached for {$tier} plan. Please upgrade your subscription."
            ]);
        }

        // POSTING LIMITS: Check daily/weekly/monthly limits (IMPLEMENTED)
        $postingLimitCheck = $this->checkPostingLimits($user);
        if (!$postingLimitCheck['allowed']) {
            return $this->response->setJSON([
                'success' => false,
                'message' => $postingLimitCheck['message'],
                'charge_required' => $postingLimitCheck['charge'] ?? 0,
            ]);
        }

        $validation = \Config\Services::validation();
        
        $rules = [
            'listing_type' => 'required|in_list[sell,rent]',
            'title' => 'required|min_length[3]|max_length[255]',
            'description' => 'required|min_length[10]',
            'category' => 'required',
            'original_price' => 'required|decimal',
            'used_times' => 'required|integer',
            'dispatch_address' => 'required',
            'dispatch_pin_code' => 'required',
            'product_images.*' => 'uploaded[product_images]|max_size[product_images,10240]|is_image[product_images]',
        ];

        // Add listing-specific validations
        if ($this->request->getPost('listing_type') === 'sell') {
            $rules['price'] = 'required|decimal';
        } else {
            $rules['rental_cost'] = 'required|decimal';
            $rules['rental_deposit'] = 'required|decimal';
        }

        if (!$this->validate($rules)) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $validation->getErrors()
            ]);
        }

        $originalPrice = floatval($this->request->getPost('original_price'));
        $usedTimes = intval($this->request->getPost('used_times'));
        $listingType = $this->request->getPost('listing_type');

        // Validate pricing (S23)
        if ($listingType === 'sell') {
            $salePrice = floatval($this->request->getPost('price'));
            if (!validateSalePrice($originalPrice, $salePrice)) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Sale price must be at least 5% less than original price'
                ]);
            }
        } else {
            $deposit = floatval($this->request->getPost('rental_deposit'));
            $rentalCost = floatval($this->request->getPost('rental_cost'));

            if (!validateDeposit($originalPrice, $deposit)) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Deposit must be at least 10% less than original price'
                ]);
            }

            if (!validateRentalCost($deposit, $rentalCost)) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Rental cost must not exceed 40% of deposit'
                ]);
            }
        }

        // S16 - Auto-tag to brand if seller has brand and reliability >= 25
        $brandId = $this->request->getPost('brand_id') ?: null;
        
        // If no brand selected but seller is eligible, auto-select their first brand
        if (!$brandId && ($user['seller_reliability_score'] ?? 0) >= 25) {
            $sellerBrand = $this->brandModel
                ->where('seller_id', $userId)
                ->first();
            
            if ($sellerBrand) {
                $brandId = $sellerBrand['id'];
            }
        }
        
        // Don't allow brand tagging if score is low
        if ($brandId && ($user['seller_reliability_score'] ?? 0) < 25) {
            $brandId = null;
        }
        
        $productData = [
            'seller_id' => $userId,
            'brand_id' => $brandId,
            'listing_type' => $listingType,
            'title' => $this->request->getPost('title'),
            'description' => $this->request->getPost('description'),
            'category' => $this->request->getPost('category'),
            'sub_category' => $this->request->getPost('sub_category'),
            'product_type' => $this->request->getPost('product_type'),
            'gender' => $this->request->getPost('gender'),
            'size' => $this->request->getPost('size'),
            'color' => $this->request->getPost('color'),
            'used_times' => $usedTimes,
            'original_price' => $originalPrice,
            'dispatch_address' => $this->request->getPost('dispatch_address'),
            'dispatch_pin_code' => $this->request->getPost('dispatch_pin_code'),
            'has_bill' => $this->request->getPost('has_bill') ? 1 : 0,
            'status' => 'pending',
        ];

        // Calculate suggested prices (S20, S21)
        if ($listingType === 'sell') {
            $productData['price'] = floatval($this->request->getPost('price'));
            $productData['suggested_sale_price'] = calculateSalePrice($originalPrice, $usedTimes);
        } else {
            $productData['rental_cost'] = floatval($this->request->getPost('rental_cost'));
            $productData['rental_deposit'] = floatval($this->request->getPost('rental_deposit'));
            $productData['fitting_charge'] = $this->request->getPost('fitting_charge');
            $productData['allow_alter_fitting'] = $this->request->getPost('allow_alter_fitting') ? 1 : 0;
            
            $rentalPrices = calculateRentalPrices($originalPrice, $usedTimes);
            $productData['suggested_rental_cost'] = $rentalPrices['rental_cost'];
        }

        $productId = $this->productModel->insert($productData);

        if (!$productId) {
            // Get database error for debugging
            $db = \Config\Database::connect();
            $error = $db->error();
            
            log_message('error', 'Product insert failed: ' . print_r($error, true));
            log_message('error', 'Product data: ' . print_r($productData, true));
            
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Failed to create product',
                'error' => ENVIRONMENT === 'development' ? $error['message'] : null,
                'debug' => ENVIRONMENT === 'development' ? $productData : null
            ]);
        }

        // Increment products uploaded count (guard update)
        try {
            if ($userId) {
                $userModel->update($userId, [
                    'products_uploaded_count' => $uploadCount + 1
                ]);
            } else {
                log_message('error', 'processUpload: missing user id when incrementing products_uploaded_count.');
            }
        } catch (\CodeIgniter\Database\Exceptions\DataException $e) {
            log_message('error', 'processUpload: failed to increment products_uploaded_count for user ' . $userId . ' - ' . $e->getMessage());
        }

        // Handle product images upload (save into public uploads for web access)
        $images = $this->request->getFiles();
        if (isset($images['product_images'])) {
            $uploadPath = FCPATH . 'uploads/products/';

            if (!is_dir($uploadPath)) {
                mkdir($uploadPath, 0777, true);
            }

            $imageCount = 0;
            foreach ($images['product_images'] as $image) {
                if ($image->isValid() && !$image->hasMoved() && $imageCount < 7) {
                    $newName = $image->getRandomName();
                    $image->move($uploadPath, $newName);
                    $insertData = [
                        'product_id' => $productId,
                        'image_path' => 'uploads/products/' . $newName,
                        'is_primary' => $imageCount === 0 ? 1 : 0,
                        'display_order' => $imageCount,
                    ];

                    $imgId = false;
                    try {
                        $imgId = $this->imageModel->insert($insertData);
                    } catch (\Exception $e) {
                        log_message('error', 'processUpload: failed to insert product image for product ' . $productId . ' - ' . $e->getMessage());
                        log_message('error', 'processUpload: image insert data: ' . print_r($insertData, true));
                    }

                    if (!$imgId) {
                        $modelErrors = method_exists($this->imageModel, 'errors') ? $this->imageModel->errors() : null;
                        log_message('error', 'processUpload: imageModel->insert returned falsy for product ' . $productId . '. Model errors: ' . print_r($modelErrors, true));
                    }
                    
                    $imageCount++;
                }
            }
        }

        // Handle bill image (save into public uploads for web access)
        $billImage = $this->request->getFile('bill_image');
        if ($billImage && $billImage->isValid()) {
            $uploadPath = FCPATH . 'uploads/bills/';
            if (!is_dir($uploadPath)) {
                mkdir($uploadPath, 0777, true);
            }

            $billName = $billImage->getRandomName();
            $billImage->move($uploadPath, $billName);

            try {
                $this->productModel->update($productId, [
                    'bill_image' => 'uploads/bills/' . $billName
                ]);
            } catch (\Exception $e) {
                log_message('error', 'processUpload: failed to update bill_image for product ' . $productId . ' - ' . $e->getMessage());
            }
        }

        // Create notification for admin
        $this->notificationModel->insert([
            'user_id' => 1, // Admin user ID (adjust as needed)
            'title' => 'New Product Upload',
            'message' => "New product '{$productData['title']}' submitted for approval",
            'type' => 'product_upload',
            'related_id' => $productId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Product uploaded successfully! Waiting for admin approval.',
            'product_id' => $productId
        ]);
    }

    public function myProducts()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);
        
        $status = $this->request->getGet('status');
        $type = $this->request->getGet('type');
        $category = $this->request->getGet('category');
        
        $builder = $this->productModel
            ->select('products.*, product_images.image_path as primary_image')
            ->join('product_images', 'product_images.product_id = products.id AND product_images.is_primary = 1', 'left')
            ->where('products.seller_id', $userId);

        if ($status) {
            $builder->where('products.status', $status);
        }
        if ($type) {
            $builder->where('products.listing_type', $type);
        }
        if ($category) {
            $builder->where('products.category', $category);
        }

        $products = $builder->orderBy('products.created_at', 'DESC')->findAll();

        $data = [
            'user' => $user,
            'products' => $products,
            'status' => $status,
        ];

        return view('seller/products', $data);
    }

    public function offers()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);
        $status = $this->request->getGet('status');
        
        // S26 - Get offers with buyer's complete reliability scores
        $builder = $this->offerModel
            // include aliases and safe defaults so views can rely on these keys
            ->select('offers.*, offers.offer_price as offered_price, "buy" as offer_type, 0 as deposit_amount, NULL as rental_start_date, NULL as rental_end_date, products.title as product_title, products.category, product_images.image_path as product_image, users.name as buyer_name, users.renter_reliability_score as buyer_renter_score, (users.renter_reliability_score + users.seller_reliability_score) / 2 as buyer_reliability_score')
            ->join('products', 'products.id = offers.product_id')
            ->join('product_images', 'product_images.product_id = products.id AND product_images.is_primary = 1', 'left')
            ->join('users', 'users.id = offers.buyer_id')
            ->where('offers.seller_id', $userId);

        if ($status) {
            $builder->where('offers.status', $status);
        }

        $offers = $builder->orderBy('offers.created_at', 'DESC')->findAll();
        
        $data = [
            'user' => $user,
            'offers' => $offers,
            'status' => $status,
        ];

        return view('seller/offers_new', $data);
    }

    public function acceptOffer($offerId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $offer = $this->offerModel->find($offerId);

        // Normalize missing fields (backwards compatibility with older schemas)
        if ($offer) {
            if (!array_key_exists('offer_type', $offer)) {
                $offer['offer_type'] = $offer['offer_type'] ?? 'buy';
            }
            if (!array_key_exists('offered_price', $offer)) {
                $offer['offered_price'] = $offer['offer_price'] ?? null;
            }
            if (!array_key_exists('deposit_amount', $offer)) {
                $offer['deposit_amount'] = $offer['deposit_amount'] ?? 0;
            }
            if (!array_key_exists('rental_start_date', $offer)) {
                $offer['rental_start_date'] = $offer['rental_start_date'] ?? null;
            }
            if (!array_key_exists('rental_end_date', $offer)) {
                $offer['rental_end_date'] = $offer['rental_end_date'] ?? null;
            }
        }
        
        if (!$offer || $offer['seller_id'] != session()->get('user_id')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid offer']);
        }

        // S22, S24 - Check for date conflicts if rental
        if ($offer['offer_type'] === 'rent' && !empty($offer['rental_start_date'])) {
            $conflicts = $this->offerModel
                ->where('product_id', $offer['product_id'])
                ->where('status', 'accepted')
                ->where('id !=', $offerId)
                ->groupStart()
                    ->where('rental_start_date <=', $offer['rental_end_date'])
                    ->where('rental_end_date >=', $offer['rental_start_date'])
                ->groupEnd()
                ->countAllResults();

            if ($conflicts > 0) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Date conflict! Product already booked for these dates.'
                ]);
            }
        }

        // Update offer with accepted_at timestamp (S27)
        $this->offerModel->update($offerId, [
            'status' => 'accepted',
            'accepted_at' => date('Y-m-d H:i:s')
        ]);

        // S18 - Create Order when offer accepted
        $product = $this->productModel->find($offer['product_id']);
        
        // Get buyer details for delivery address
        $buyer = $this->userModel->find($offer['buyer_id']);
        
        // Build order data using keys expected by OrderModel
        $orderData = [
            'product_id' => $offer['product_id'],
            'buyer_id' => $offer['buyer_id'],
            'seller_id' => $offer['seller_id'],
            // OrderModel expects `order_type` and `final_price`
            'order_type' => $offer['offer_type'] ?? 'buy',
            'final_price' => $offer['offered_price'] ?? 0,
            'delivery_address' => $buyer['address'] ?? 'No address provided',
            'delivery_pin_code' => $buyer['pin_code'] ?? '000000',
            'status' => 'pending', // Will progress to: dispatched → delivered → completed
            'deposit_amount' => $offer['deposit_amount'] ?? null,
        ];

        $orderId = $this->orderModel->insert($orderData);

        if (!$orderId) {
            // Order insert failed; log DB error and return failure to avoid FK violation
            $db = \Config\Database::connect();
            $error = $db->error();
            log_message('error', 'Order insert failed after offer acceptance: ' . print_r($error, true));
            log_message('error', 'Order data: ' . print_r($orderData, true));

            return $this->response->setJSON([
                'success' => false,
                'message' => 'Failed to create order',
                'error' => ENVIRONMENT === 'development' ? $error['message'] : null
            ]);
        }

        // Create initial order status history
        $statusHistoryModel = new \App\Models\OrderStatusHistoryModel();
        $statusHistoryModel->insert([
            'order_id' => $orderId,
            'status' => 'pending',
            'notes' => 'Order created - Offer accepted by seller',
        ]);

        // Create notification for buyer (S30)
        $this->notificationModel->insert([
            'user_id' => $offer['buyer_id'],
            'title' => 'Offer Accepted',
            'message' => 'Your offer has been accepted! Order #FLX' . str_pad($orderId, 6, '0', STR_PAD_LEFT) . ' created.',
            'type' => 'offer_accepted',
            'related_id' => $offerId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Offer accepted and order created successfully',
            'order_id' => $orderId
        ]);
    }

    public function rejectOffer($offerId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $offer = $this->offerModel->find($offerId);
        
        if (!$offer || $offer['seller_id'] != session()->get('user_id')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid offer']);
        }

        // S27 - If accepted, check if within 1 day window
        // S28 - If rental, check if before 1 day of pickup
        if ($offer['status'] === 'accepted') {
            $canReject = false;
            $reason = '';

            // S27: Within 1 day of acceptance
            if (!empty($offer['accepted_at'])) {
                $acceptedTime = strtotime($offer['accepted_at']);
                $oneDayLater = $acceptedTime + 86400;
                if (time() < $oneDayLater) {
                    $canReject = true;
                    $reason = 'within 24-hour acceptance window';
                }
            }

            // S28: Before 1 day of pickup (for rentals)
            if (!$canReject && $offer['offer_type'] === 'rent' && !empty($offer['rental_start_date'])) {
                $pickupDate = strtotime($offer['rental_start_date']);
                $oneDayBefore = $pickupDate - 86400;
                if (time() < $oneDayBefore) {
                    $canReject = true;
                    $reason = 'before pickup date';
                }
            }

            if (!$canReject) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Cannot reject: Rejection window expired (must reject within 1 day of acceptance OR 1 day before pickup)'
                ]);
            }
        }

        $this->offerModel->update($offerId, ['status' => 'rejected']);

        // S30 - Notify buyer immediately
        $this->notificationModel->insert([
            'user_id' => $offer['buyer_id'],
            'title' => 'Offer Rejected',
            'message' => 'Your offer has been rejected by the seller',
            'type' => 'offer_rejected',
            'related_id' => $offerId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Offer rejected successfully'
        ]);
    }

    public function orders()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userId = session()->get('user_id');
        $status = $this->request->getGet('status');
        
        $data = [
            'user' => session()->get(),
            'orders' => $this->orderModel->getSellerOrders($userId, $status),
            'current_status' => $status,
        ];

        return view('seller/orders', $data);
    }

    public function createBrand()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userId = session()->get('user_id');
        
        if (!$this->brandModel->canCreateBrand($userId)) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'You need a reliability score of at least 25 to create a brand'
            ]);
        }

        $validation = \Config\Services::validation();
        
        if (!$this->validate([
            'brand_name' => 'required|min_length[2]|max_length[100]',
            'logo' => 'uploaded[logo]|max_size[logo,1024]|is_image[logo]',
        ])) {
            return $this->response->setJSON([
                'success' => false,
                'errors' => $validation->getErrors()
            ]);
        }

        $brandData = [
            'seller_id' => $userId,
            'brand_name' => $this->request->getPost('brand_name'),
            'description' => $this->request->getPost('description'),
        ];

        // Handle logo upload
        $logo = $this->request->getFile('logo');
        if ($logo->isValid()) {
            $uploadPath = WRITEPATH . 'uploads/brands/';
            if (!is_dir($uploadPath)) {
                mkdir($uploadPath, 0777, true);
            }
            
            $logoName = $logo->getRandomName();
            $logo->move($uploadPath, $logoName);
            $brandData['logo'] = 'uploads/brands/' . $logoName;
        }

        $brandId = $this->brandModel->insert($brandData);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Brand created successfully',
            'brand_id' => $brandId
        ]);
    }

    public function transactions()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        // Get filters from request
        $type = $this->request->getGet('type');
        $status = $this->request->getGet('status');
        $fromDate = $this->request->getGet('from_date');

        // Build query for transactions
        $builder = $this->orderModel
            ->select('orders.*, products.title as product_title, products.category, 
                      users.name as buyer_name, users.email as buyer_email, 
                      users.renter_reliability_score as buyer_rating,
                      product_images.image_path as product_image')
            ->join('products', 'products.id = orders.product_id')
            ->join('users', 'users.id = orders.buyer_id')
            ->join('product_images', 'product_images.product_id = products.id AND product_images.is_primary = 1', 'left')
            ->where('orders.seller_id', $userId);

        if ($type) {
            $builder->where('orders.type', $type);
        }
        if ($status) {
            $builder->where('orders.status', $status);
        }
        if ($fromDate) {
            $builder->where('orders.created_at >=', $fromDate);
        }

        $transactions = $builder->orderBy('orders.created_at', 'DESC')->findAll();

        // Get status history for each transaction
        $statusHistoryModel = new \App\Models\OrderStatusHistoryModel();
        foreach ($transactions as &$transaction) {
            $transaction['status_history'] = $statusHistoryModel
                ->where('order_id', $transaction['id'])
                ->orderBy('created_at', 'ASC')
                ->findAll();
        }

        $data = [
            'user' => $user,
            'transactions' => $transactions,
        ];

        return view('seller/transactions', $data);
    }

    // S15 - Brand Management Page
    public function brands()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        $brands = $this->brandModel
            ->where('seller_id', $userId)
            ->findAll();

        // Get product count for each brand
        foreach ($brands as &$brand) {
            $brand['product_count'] = $this->productModel
                ->where('brand_id', $brand['id'])
                ->countAllResults();
        }

        $totalProducts = $this->productModel
            ->where('seller_id', $userId)
            ->where('brand_id IS NOT NULL')
            ->countAllResults();

        $data = [
            'user' => $user,
            'brands' => $brands,
            'total_products' => $totalProducts,
        ];

        return view('seller/brands', $data);
    }

    // Update Brand
    public function updateBrand()
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $userId = session()->get('user_id');
        $brandId = $this->request->getPost('brand_id');
        
        $brand = $this->brandModel->find($brandId);
        
        if (!$brand || $brand['seller_id'] != $userId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid brand']);
        }

        $this->brandModel->update($brandId, [
            'brand_name' => $this->request->getPost('brand_name'),
            'description' => $this->request->getPost('description'),
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Brand updated successfully'
        ]);
    }

    // Delete Brand
    public function deleteBrand($brandId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $userId = session()->get('user_id');
        $brand = $this->brandModel->find($brandId);
        
        if (!$brand || $brand['seller_id'] != $userId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid brand']);
        }

        // Check if brand has products
        $hasProducts = $this->productModel
            ->where('brand_id', $brandId)
            ->countAllResults() > 0;

        if ($hasProducts) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Cannot delete brand with existing products. Remove products first.'
            ]);
        }

        $this->brandModel->delete($brandId);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Brand deleted successfully'
        ]);
    }

    // S29-S33: Order Management
    public function orderDetails($orderId)
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userId = session()->get('user_id');
        $order = $this->orderModel->find($orderId);

        if (!$order || $order['seller_id'] != $userId) {
            return redirect()->to('/seller/orders')->with('error', 'Order not found');
        }

        $userModel = new UserModel();
        $statusHistoryModel = new OrderStatusHistoryModel();

        $data = [
            'user' => $userModel->find($userId),
            'order' => $order,
            'buyer' => $userModel->find($order['buyer_id']),
            'product' => $this->productModel->find($order['product_id']),
            'status_history' => $statusHistoryModel->where('order_id', $orderId)->orderBy('created_at', 'ASC')->findAll(),
        ];

        return view('seller/order_details', $data);
    }

    public function markDispatched($orderId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $userId = session()->get('user_id');
        $order = $this->orderModel->find($orderId);

        if (!$order || $order['seller_id'] != $userId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid order']);
        }

        if ($order['status'] !== 'confirmed') {
            return $this->response->setJSON(['success' => false, 'message' => 'Order cannot be dispatched']);
        }

        $this->orderModel->update($orderId, ['status' => 'dispatched']);

        // Add status history
        $statusHistoryModel = new OrderStatusHistoryModel();
        $statusHistoryModel->insert([
            'order_id' => $orderId,
            'status' => 'dispatched',
            'changed_by' => $userId,
        ]);

        // Notify buyer
        $this->notificationModel->insert([
            'user_id' => $order['buyer_id'],
            'title' => 'Order Dispatched',
            'message' => 'Your order has been dispatched',
            'type' => 'order_status',
            'related_id' => $orderId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Order marked as dispatched'
        ]);
    }

    // S29: Analytics Dashboard
    public function analytics()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        // Total stats
        $totalProducts = $this->productModel->where('seller_id', $userId)->countAllResults();
        $totalOrders = $this->orderModel->where('seller_id', $userId)->countAllResults();
        $totalRevenue = $this->orderModel->where('seller_id', $userId)->selectSum('final_price')->first()['final_price'] ?? 0;

        // This month stats
        $thisMonth = date('Y-m-01');
        $monthOrders = $this->orderModel->where('seller_id', $userId)->where('created_at >=', $thisMonth)->countAllResults();
        $monthRevenue = $this->orderModel->where('seller_id', $userId)->where('created_at >=', $thisMonth)->selectSum('final_price')->first()['final_price'] ?? 0;

        // Top products
        $topProducts = $this->productModel
            ->select('products.*, COUNT(orders.id) as order_count, SUM(orders.final_price) as revenue')
            ->join('orders', 'orders.product_id = products.id', 'left')
            ->where('products.seller_id', $userId)
            ->groupBy('products.id')
            ->orderBy('order_count', 'DESC')
            ->limit(5)
            ->findAll();

        // Category breakdown
        $categoryStats = $this->productModel
            ->select('category, COUNT(*) as count')
            ->where('seller_id', $userId)
            ->groupBy('category')
            ->findAll();

        // Reviews
        $reviewModel = new ReviewModel();
        $avgRating = $reviewModel->getAverageRating($userId);
        $reviewCount = $reviewModel->where('reviewed_id', $userId)->countAllResults();

        $data = [
            'user' => $user,
            'stats' => [
                'total_products' => $totalProducts,
                'total_orders' => $totalOrders,
                'total_revenue' => $totalRevenue,
                'month_orders' => $monthOrders,
                'month_revenue' => $monthRevenue,
                'avg_rating' => $avgRating,
                'review_count' => $reviewCount,
            ],
            'top_products' => $topProducts,
            'category_stats' => $categoryStats,
        ];

        return view('seller/analytics', $data);
    }

    // Profile page
    public function profile()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        $data = ['user' => $user];
        return view('seller/profile', $data);
    }

    // Subscription page
    public function subscription()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        $data = ['user' => $user];
        return view('seller/subscription', $data);
    }

    // Notifications page
    public function notifications()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userId = session()->get('user_id');
        $notifications = $this->notificationModel->getUserNotifications($userId, false);

        $data = [
            'user' => session()->get(),
            'notifications' => $notifications
        ];
        return view('seller/notifications', $data);
    }

    // Help page
    public function help()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $data = ['user' => session()->get()];
        return view('seller/help', $data);
    }

    // AJAX: Get listing types
    public function getListingTypes()
    {
        $db = \Config\Database::connect();
        $types = $db->table('listing_types')->get()->getResultArray();
        return $this->response->setJSON(['success' => true, 'data' => $types]);
    }

    // AJAX: Get product types by listing type
    public function getProductTypesByListing($listingTypeId = 0)
    {
        $db = \Config\Database::connect();
        $types = $db->table('product_types')->where('listing_type_id', (int)$listingTypeId)->get()->getResultArray();
        return $this->response->setJSON(['success' => true, 'data' => $types]);
    }

    // AJAX: Get categories by product type
    public function getCategoriesByProductType($productTypeId = 0)
    {
        $db = \Config\Database::connect();
        // Be tolerant to schema differences: prefer parent_id, fallback to product_type_id, otherwise return all
        $cats = [];
        try {
            $fields = $db->getFieldNames('categories');
            if ($productTypeId && in_array('parent_id', $fields)) {
                $cats = $db->table('categories')->where('parent_id', (int)$productTypeId)->get()->getResultArray();
            } elseif ($productTypeId && in_array('product_type_id', $fields)) {
                $cats = $db->table('categories')->where('product_type_id', (int)$productTypeId)->get()->getResultArray();
            } else {
                $cats = $db->table('categories')->get()->getResultArray();
            }
        } catch (\Exception $e) {
            $cats = [];
        }
        return $this->response->setJSON(['success' => true, 'data' => $cats]);
    }

    // POSTING LIMITS: Check if seller can post (IMPLEMENTED)
    private function checkPostingLimits($user)
    {
        $userId = $user['id'];
        $tier = $user['subscription_tier'] ?? 'free';
        $today = date('Y-m-d');
        
        $db = \Config\Database::connect();

        // Reset counters if needed
        $lastPostDate = $user['last_post_date'] ?? null;
        $dailyCount = $user['daily_posts_count'] ?? 0;
        $weeklyCount = $user['weekly_posts_count'] ?? 0;
        $monthlyCount = $user['monthly_posts_count'] ?? 0;

        // Reset daily count if it's a new day
        if ($lastPostDate !== $today) {
            $dailyCount = 0;
        }

        // Reset weekly count if it's a new week
        if ($lastPostDate && date('W', strtotime($today)) !== date('W', strtotime($lastPostDate))) {
            $weeklyCount = 0;
        }

        // Reset monthly count if it's a new month
        if ($lastPostDate && date('Y-m', strtotime($today)) !== date('Y-m', strtotime($lastPostDate))) {
            $monthlyCount = 0;
        }

        // Get posting limits for this tier
        $limits = $db->table('posting_limits')
                     ->where('subscription_tier', $tier)
                     ->get()
                     ->getResultArray();

        $limitMap = [];
        foreach ($limits as $limit) {
            $limitMap[$limit['limit_type']] = $limit;
        }

        // Check daily limit
        $dailyLimit = $limitMap['daily'] ?? null;
        $weeklyLimit = $limitMap['weekly'] ?? null;
        $monthlyLimit = $limitMap['monthly'] ?? null;

        $totalCharge = 0;
        $messages = [];

        // Check each limit
        if ($dailyLimit && $dailyCount >= $dailyLimit['max_posts']) {
            $extraPosts = $dailyCount - $dailyLimit['max_posts'] + 1;
            $charge = $extraPosts * $dailyLimit['charge_per_extra_post'];
            $totalCharge += $charge;
            $messages[] = "Daily limit exceeded. Charge: ₹{$charge}";
        }

        if ($weeklyLimit && $weeklyCount >= $weeklyLimit['max_posts']) {
            $extraPosts = $weeklyCount - $weeklyLimit['max_posts'] + 1;
            $charge = $extraPosts * $weeklyLimit['charge_per_extra_post'];
            $totalCharge += $charge;
            $messages[] = "Weekly limit exceeded. Charge: ₹{$charge}";
        }

        if ($monthlyLimit && $monthlyCount >= $monthlyLimit['max_posts']) {
            $extraPosts = $monthlyCount - $monthlyLimit['max_posts'] + 1;
            $charge = $extraPosts * $monthlyLimit['charge_per_extra_post'];
            $totalCharge += $charge;
            $messages[] = "Monthly limit exceeded. Charge: ₹{$charge}";
        }

        // Update counters (guard and catch DB exceptions to avoid crashing on empty datasets)
        $userModel = new \App\Models\UserModel();
        $updateData = [
            'daily_posts_count' => $dailyCount + 1,
            'weekly_posts_count' => $weeklyCount + 1,
            'monthly_posts_count' => $monthlyCount + 1,
            'last_post_date' => $today,
        ];

        if ($userId) {
            try {
                $userModel->update($userId, $updateData);
            } catch (\CodeIgniter\Database\Exceptions\DataException $e) {
                log_message('error', 'Posting limits: failed to update counters for user ' . $userId . ' - ' . $e->getMessage());
            }
        } else {
            log_message('error', 'Posting limits: missing user id, skipping update. User data: ' . print_r($user, true));
        }

        if ($totalCharge > 0) {
            // Return charge info (in real app, integrate with payment gateway)
            return [
                'allowed' => true, // Allow posting but with charge
                'charge' => $totalCharge,
                'message' => implode(' ', $messages) . " Total charge: ₹{$totalCharge}",
            ];
        }

        return ['allowed' => true, 'charge' => 0, 'message' => 'Posting allowed'];
    }

    // View Fitting Alteration Requests (IMPLEMENTED)
    public function fittingAlterationRequests()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }

        $userModel = new \App\Models\UserModel();
        $userId = session()->get('user_id');
        $user = $userModel->find($userId);

        $db = \Config\Database::connect();
        $requests = $db->table('fitting_alteration_requests')
                       ->select('fitting_alteration_requests.*, products.title as product_title, users.name as buyer_name, users.email as buyer_email')
                       ->join('products', 'products.id = fitting_alteration_requests.product_id')
                       ->join('users', 'users.id = fitting_alteration_requests.buyer_id')
                       ->where('fitting_alteration_requests.seller_id', $userId)
                       ->orderBy('fitting_alteration_requests.created_at', 'DESC')
                       ->get()
                       ->getResultArray();

        $data = [
            'user' => $user,
            'requests' => $requests,
        ];

        return view('seller/fitting_alteration_requests', $data);
    }

    // Respond to Fitting Alteration Request (IMPLEMENTED)
    public function respondToFittingAlteration($requestId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $userId = session()->get('user_id');
        $db = \Config\Database::connect();

        $request = $db->table('fitting_alteration_requests')
                      ->where('id', $requestId)
                      ->where('seller_id', $userId)
                      ->get()
                      ->getRowArray();

        if (!$request) {
            return $this->response->setJSON(['success' => false, 'message' => 'Request not found']);
        }

        $status = $this->request->getPost('status'); // accepted or rejected
        $response = $this->request->getPost('response');

        $db->table('fitting_alteration_requests')
           ->where('id', $requestId)
           ->update([
               'status' => $status,
               'seller_response' => $response,
               'updated_at' => date('Y-m-d H:i:s'),
           ]);

        // Notify buyer
        $this->notificationModel->insert([
            'user_id' => $request['buyer_id'],
            'title' => 'Fitting Alteration Response',
            'message' => "Your fitting alteration request was {$status}",
            'type' => 'alteration_response',
            'related_id' => $requestId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Response sent successfully'
        ]);
    }

    // ORDER STATUS: Confirm rental return received (IMPLEMENTED)
    public function confirmRentalReturn($orderId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $userId = session()->get('user_id');
        $order = $this->orderModel->find($orderId);

        if (!$order || $order['seller_id'] != $userId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid order']);
        }

        if ($order['status'] !== 'returned') {
            return $this->response->setJSON(['success' => false, 'message' => 'Order cannot be confirmed']);
        }

        // Update order status to completed
        $this->orderModel->updateOrderStatus($orderId, 'completed', $userId, 'Seller confirmed rental return');

        // Notify buyer
        $this->notificationModel->insert([
            'user_id' => $order['buyer_id'],
            'title' => 'Rental Return Confirmed',
            'message' => "Your rental return for order #{$order['order_number']} has been confirmed",
            'type' => 'rental_confirmed',
            'related_id' => $orderId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Rental return confirmed successfully'
        ]);
    }

    // ORDER STATUS: Complete sale order (IMPLEMENTED)
    public function completeSaleOrder($orderId)
    {
        if (!session()->get('logged_in')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Not logged in']);
        }

        $userId = session()->get('user_id');
        $order = $this->orderModel->find($orderId);

        if (!$order || $order['seller_id'] != $userId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Invalid order']);
        }

        if ($order['order_type'] !== 'buy' || $order['status'] !== 'delivered') {
            return $this->response->setJSON(['success' => false, 'message' => 'Order cannot be completed']);
        }

        // Update order status to completed
        $this->orderModel->updateOrderStatus($orderId, 'completed', $userId, 'Sale order completed');

        // Notify buyer
        $this->notificationModel->insert([
            'user_id' => $order['buyer_id'],
            'title' => 'Order Completed',
            'message' => "Your order #{$order['order_number']} has been completed",
            'type' => 'order_completed',
            'related_id' => $orderId,
        ]);

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Order completed successfully'
        ]);
    }

    // AJAX: Get sub-categories by category
    public function getSubCategoriesByCategory($categoryId = 0)
    {
        $db = \Config\Database::connect();
        $subs = $db->table('sub_categories')->where('category_id', (int)$categoryId)->get()->getResultArray();
        return $this->response->setJSON(['success' => true, 'data' => $subs]);
    }
}

