<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Order;
use App\Models\Payment;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class WaiterController extends Controller
{
    /**
     * Get waiter's own sales performance
     */
    public function getMySales(Request $request): JsonResponse
    {
        $user = $request->user();
        
        if ($user->role !== 'waiter' && !$user->hasPermission('view_own_sales')) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $dateFrom = $request->get('date_from', Carbon::today()->toDateString());
        $dateTo = $request->get('date_to', Carbon::today()->toDateString());

        $salesData = $this->getWaiterSalesData($user->id, $dateFrom, $dateTo);

        return response()->json($salesData);
    }

    /**
     * Get all waiters' performance (Manager/Admin only)
     */
    public function getWaitersPerformance(Request $request): JsonResponse
    {
        $user = $request->user();
        
        if (!in_array($user->role, ['admin', 'manager'])) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $dateFrom = $request->get('date_from', Carbon::today()->toDateString());
        $dateTo = $request->get('date_to', Carbon::today()->toDateString());
        $branchId = $request->get('branch_id');

        $query = User::where('role', 'waiter')->where('is_active', true);

        // Apply branch filter for managers
        if ($user->role === 'manager') {
            $query->where('restaurant_id', $user->restaurant_id);
        }

        if ($branchId) {
            $query->where('branch_id', $branchId);
        }

        $waiters = $query->get();
        $performanceData = [];

        foreach ($waiters as $waiter) {
            $salesData = $this->getWaiterSalesData($waiter->id, $dateFrom, $dateTo);
            $performanceData[] = [
                'waiter' => [
                    'id' => $waiter->id,
                    'name' => $waiter->name,
                    'email' => $waiter->email,
                    'employee_id' => $waiter->employee_id,
                    'branch' => $waiter->branch?->name,
                ],
                'performance' => $salesData
            ];
        }

        // Sort by total sales descending
        usort($performanceData, function($a, $b) {
            return $b['performance']['total_sales'] <=> $a['performance']['total_sales'];
        });

        return response()->json([
            'date_range' => ['from' => $dateFrom, 'to' => $dateTo],
            'waiters' => $performanceData,
            'summary' => $this->calculateTeamSummary($performanceData)
        ]);
    }

    /**
     * Get waiter's detailed order history
     */
    public function getMyOrders(Request $request): JsonResponse
    {
        $user = $request->user();
        
        if ($user->role !== 'waiter' && !$user->hasPermission('view_own_sales')) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $dateFrom = $request->get('date_from', Carbon::today()->toDateString());
        $dateTo = $request->get('date_to', Carbon::today()->toDateString());
        $status = $request->get('status', 'all');

        $query = Order::with(['customer', 'table', 'items.menuItem', 'payments'])
                     ->where('user_id', $user->id)
                     ->whereBetween('created_at', [
                         Carbon::parse($dateFrom)->startOfDay(),
                         Carbon::parse($dateTo)->endOfDay()
                     ]);

        if ($status !== 'all') {
            $query->where('status', $status);
        }

        $orders = $query->orderBy('created_at', 'desc')->paginate(2000);

        return response()->json($orders);
    }

    /**
     * Get waiter's payment history
     */
    public function getMyPayments(Request $request): JsonResponse
    {
        $user = $request->user();
        
        if ($user->role !== 'waiter' && !$user->hasPermission('view_own_sales')) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $dateFrom = $request->get('date_from', Carbon::today()->toDateString());
        $dateTo = $request->get('date_to', Carbon::today()->toDateString());

        $payments = Payment::with(['order.customer', 'order.table'])
                          ->whereHas('order', function($query) use ($user) {
                              $query->where('user_id', $user->id);
                          })
                          ->whereBetween('created_at', [
                              Carbon::parse($dateFrom)->startOfDay(),
                              Carbon::parse($dateTo)->endOfDay()
                          ])
                          ->orderBy('created_at', 'desc')
                          ->paginate(2000);

        return response()->json($payments);
    }

    /**
     * Get waiter leaderboard
     */
    public function getLeaderboard(Request $request): JsonResponse
    {
        $user = $request->user();
        
        if (!in_array($user->role, ['admin', 'manager', 'waiter'])) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $period = $request->get('period', 'today'); // today, week, month
        $branchId = $request->get('branch_id');

        $dateRange = $this->getDateRange($period);

        $query = DB::table('orders')
                   ->join('users', 'orders.user_id', '=', 'users.id')
                   ->leftJoin('branches', 'users.branch_id', '=', 'branches.id')
                   ->where('users.role', 'waiter')
                   ->where('users.is_active', true)
                   ->where('orders.status', '!=', 'cancelled')
                   ->whereBetween('orders.created_at', $dateRange);

        // Apply branch filter
        if ($user->role === 'manager') {
            $query->where('users.restaurant_id', $user->restaurant_id);
        }

        if ($branchId) {
            $query->where('users.branch_id', $branchId);
        }

        $leaderboard = $query->select([
                                'users.id',
                                'users.name',
                                'users.employee_id',
                                'branches.name as branch_name',
                                DB::raw('COUNT(orders.id) as total_orders'),
                                DB::raw('SUM(orders.total_amount) as total_sales'),
                                DB::raw('AVG(orders.total_amount) as avg_order_value'),
                                DB::raw('SUM(CASE WHEN orders.payment_status = "paid" THEN orders.total_amount ELSE 0 END) as paid_sales')
                            ])
                            ->groupBy('users.id', 'users.name', 'users.employee_id', 'branches.name')
                            ->orderBy('total_sales', 'desc')
                            ->get();

        return response()->json([
            'period' => $period,
            'date_range' => $dateRange,
            'leaderboard' => $leaderboard,
            'current_user_rank' => $this->getCurrentUserRank($leaderboard, $user->id)
        ]);
    }

    /**
     * Get waiter's daily summary
     */
    public function getDailySummary(Request $request): JsonResponse
    {
        $user = $request->user();
        
        if ($user->role !== 'waiter' && !$user->hasPermission('view_own_sales')) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $date = $request->get('date', Carbon::today()->toDateString());
        $salesData = $this->getWaiterSalesData($user->id, $date, $date);

        // Get hourly breakdown
        $hourlyBreakdown = Order::where('user_id', $user->id)
                               ->whereDate('created_at', $date)
                               ->where('status', '!=', 'cancelled')
                               ->select([
                                   DB::raw('HOUR(created_at) as hour'),
                                   DB::raw('COUNT(*) as orders_count'),
                                   DB::raw('SUM(total_amount) as sales_amount')
                               ])
                               ->groupBy('hour')
                               ->orderBy('hour')
                               ->get();

        // Get payment method breakdown
        $paymentBreakdown = Payment::whereHas('order', function($query) use ($user, $date) {
                                   $query->where('user_id', $user->id)
                                         ->whereDate('created_at', $date);
                               })
                               ->select([
                                   'method as payment_method',
                                   DB::raw('COUNT(*) as transaction_count'),
                                   DB::raw('SUM(amount) as total_amount')
                               ])
                               ->groupBy('method')
                               ->get();

        return response()->json([
            'date' => $date,
            'summary' => $salesData,
            'hourly_breakdown' => $hourlyBreakdown,
            'payment_breakdown' => $paymentBreakdown
        ]);
    }

    /**
     * Private helper methods
     */
    private function getWaiterSalesData(int $waiterId, string $dateFrom, string $dateTo): array
    {
        $orders = Order::where('user_id', $waiterId)
                      ->whereBetween('created_at', [
                          Carbon::parse($dateFrom)->startOfDay(),
                          Carbon::parse($dateTo)->endOfDay()
                      ])
                      ->where('status', '!=', 'cancelled');

        $totalOrders = $orders->count();
        $totalSales = $orders->sum('total_amount');
        $paidSales = $orders->where('payment_status', 'paid')->sum('total_amount');
        $pendingSales = $orders->where('payment_status', 'pending')->sum('total_amount');
        $avgOrderValue = $totalOrders > 0 ? $totalSales / $totalOrders : 0;

        // Get payment method breakdown
        $paymentMethods = Payment::whereHas('order', function($query) use ($waiterId, $dateFrom, $dateTo) {
                                 $query->where('user_id', $waiterId)
                                       ->whereBetween('created_at', [
                                           Carbon::parse($dateFrom)->startOfDay(),
                                           Carbon::parse($dateTo)->endOfDay()
                                       ]);
                             })
                             ->select([
                                 'method as payment_method',
                                 DB::raw('COUNT(*) as count'),
                                 DB::raw('SUM(amount) as total')
                             ])
                             ->groupBy('method')
                             ->get()
                             ->keyBy('payment_method');

        // Get order status breakdown
        $statusBreakdown = Order::where('user_id', $waiterId)
                               ->whereBetween('created_at', [
                                   Carbon::parse($dateFrom)->startOfDay(),
                                   Carbon::parse($dateTo)->endOfDay()
                               ])
                               ->select([
                                   'status',
                                   DB::raw('COUNT(*) as count')
                               ])
                               ->groupBy('status')
                               ->get()
                               ->keyBy('status');

        return [
            'total_orders' => $totalOrders,
            'total_sales' => round($totalSales, 2),
            'paid_sales' => round($paidSales, 2),
            'pending_sales' => round($pendingSales, 2),
            'avg_order_value' => round($avgOrderValue, 2),
            'payment_methods' => $paymentMethods,
            'order_status' => $statusBreakdown,
            'date_range' => ['from' => $dateFrom, 'to' => $dateTo]
        ];
    }

    private function calculateTeamSummary(array $performanceData): array
    {
        $totalSales = 0;
        $totalOrders = 0;
        $activeWaiters = count($performanceData);

        foreach ($performanceData as $waiter) {
            $totalSales += $waiter['performance']['total_sales'];
            $totalOrders += $waiter['performance']['total_orders'];
        }

        return [
            'total_waiters' => $activeWaiters,
            'total_sales' => round($totalSales, 2),
            'total_orders' => $totalOrders,
            'avg_sales_per_waiter' => $activeWaiters > 0 ? round($totalSales / $activeWaiters, 2) : 0,
            'avg_orders_per_waiter' => $activeWaiters > 0 ? round($totalOrders / $activeWaiters, 2) : 0
        ];
    }

    private function getDateRange(string $period): array
    {
        return match($period) {
            'today' => [Carbon::today()->startOfDay(), Carbon::today()->endOfDay()],
            'week' => [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()],
            'month' => [Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth()],
            default => [Carbon::today()->startOfDay(), Carbon::today()->endOfDay()]
        };
    }

    private function getCurrentUserRank(object $leaderboard, int $userId): ?int
    {
        foreach ($leaderboard as $index => $waiter) {
            if ($waiter->id == $userId) {
                return $index + 1;
            }
        }
        return null;
    }
}