<?php

namespace App\Http\Controllers\Api\User;

use App\Http\Controllers\Controller;
use App\Http\Controllers\User\BotController;
use App\Models\Bot;
use App\Models\BotActivation;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Carbon;
use App\Models\Notification;

class BotApiController extends Controller
{
    protected $botController;

    public function __construct()
    {
        $this->botController = new BotController();
    }

    /**
     * Get all bots and activations
     * @return JsonResponse
     */
    public function index(): JsonResponse
    {
        try {
            $user = auth()->user();

            $bots = Bot::where('status', 1)->get();
            $activations = $user->botActivations()
                ->with('bot')
                ->orderBy('id', 'DESC')
                ->get();

            if (request()->bot) {
                $histories = $user->botHistory()
                    ->with(['botActivation.bot'])
                    ->whereHas('botActivation.bot', function ($query) {
                        $query->where('name', 'LIKE', '%' . request()->bot . '%');
                    })
                    ->orderBy('timestamp', 'DESC')
                    ->get();
            } else {
                $histories = $user->botHistory()
                    ->with(['botActivation.bot'])
                    ->orderBy('timestamp', 'DESC')
                    ->get();
            }

            $startDate = Carbon::now()->subDays(29);
            $endDate = Carbon::now();

            $chart_data = $user->botHistory()
                ->selectRaw('DATE(created_at) as date, SUM(profit) as total_profit, SUM(profit_percent) as total_profit_percent')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                ->orderBy('date')
                ->get();

            $graph_info = [];
            $days = [];
            $profits = [];
            $daily_data = [];

            $currentDate = $startDate;
            while ($currentDate <= $endDate) {
                $formatted_date = $currentDate->format('d-m');
                $graph_info[$formatted_date] = 0;

                $formatted_date_day = $currentDate->format('d-m-Y');
                $daily_data[$formatted_date_day] = ['profit' => 0, 'profit_percent' => 0];

                $currentDate->addDay();
                array_push($days, $formatted_date);
            }

            foreach ($chart_data as $data) {
                $formatted_date = date('d-m', strtotime($data->date));
                $graph_info[$formatted_date] = $data->total_profit;

                $formatted_date_day = date('d-m-Y', strtotime($data->date));
                $daily_data[$formatted_date_day] = ['profit' => $data->total_profit, 'profit_percent' => $data->total_profit_percent];
            }

            uksort($daily_data, 'compareDatesDesc');

            foreach ($graph_info as $day => $profit) {
                array_push($profits, $profit);
            }

            return response()->json([
                'status' => 'success',
                'data' => [
                    'bots' => $bots,
                    'activations' => $activations,
                    'histories' => $histories,
                    'days' => $days,
                    'profits' => $profits,
                    'daily_data' => $daily_data
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch bot data',
                'error' => $e->getMessage()
            ], 500);
        }
    }
    
    // topup funds to bot
    public function topupBot(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'bot_id' => 'required',
                'bot_activation_id' => 'required',
                'capital' => 'required|numeric',
            ]);

            $capital = $request->capital;
            $user = auth()->user();

            if ($user->balance < $capital) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Insufficient balance!'
                ], 422);
            }

            $capital = floatval($capital);
            if ($capital <= 0) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Invalid balance!'
                ], 422);
            }

            $bot = Bot::where('id', $request->bot_id)->first();

            if (!$bot) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Error accessing bot'
                ], 422);
            }

            // if ($capital < $bot->min || $capital > $bot->max) {
            //     return response()->json([
            //         'status' => 'error',
            //         'message' => 'Portfolio range for capital is ' . site('currency') . $bot->min . ' - ' . site('currency') . $bot->max
            //     ], 422);
            // }

            $debit = User::find($user->id);
            $debit->balance = $user->balance - $capital;
            $debit->save();

            recordNewTransaction($capital, $user->id, 'debit', "Bot [$bot->name] Topup");

            $duration = strtotime("+ $bot->duration $bot->duration_type");

            $activation = BotActivation::where('id', $request->bot_activation_id)->first();
            $activation->balance += $capital;
            $activation->capital += $capital;
            $activation->save();

            sendNewBotActivationMail($activation);
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Bot topup";
            $notification->message = "Bot Topup Successfull!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Bot Topup Successfull',
                'data' => [
                    'activation' => $activation,
                    'user_balance' => $debit->balance
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to activate bot',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Activate a bot
     * @param Request $request
     * @return JsonResponse
     */
    public function activateBot(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'bot_id' => 'required',
                'capital' => 'required|numeric',
            ]);

            $capital = $request->capital;
            $user = auth()->user();
            
            //todo:: limit user to only activate not more than 6 bots
             // ✅ Limit user to only activate not more than 6 bots
            $activeBotsCount = BotActivation::where('user_id', $user->id)
                ->where('status', 'active')
                ->count();
    
            if ($activeBotsCount >= 6) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'You can only activate up to 6 bots!'
                ], 422);
            }

            if ($user->balance < $capital) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Insufficient balance!'
                ], 422);
            }

            $capital = floatval($capital);
            if ($capital <= 0) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Invalid balance!'
                ], 422);
            }

            $bot = Bot::where('id', $request->bot_id)->first();

            if (!$bot) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Error accessing bot'
                ], 422);
            }

            if ($capital < $bot->min || $capital > $bot->max) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Portfolio range for capital is ' . site('currency') . $bot->min . ' - ' . site('currency') . $bot->max
                ], 422);
            }

            $debit = User::find($user->id);
            $debit->balance = $user->balance - $capital;
            $debit->save();

            recordNewTransaction($capital, $user->id, 'debit', "Bot [$bot->name] activation");

            $duration = strtotime("+ $bot->duration $bot->duration_type");

            $activation = new BotActivation();
            $activation->user_id = $user->id;
            $activation->balance = $capital;
            $activation->bot_id = $bot->id;
            $activation->capital = $capital;
            $activation->profit = 0;
            $activation->expires_in = $duration;
            $activation->daily_timestamp = now()->addDays(-1)->timestamp;
            $activation->daily_sequence = json_encode([]);
            $activation->gen_timestamps = json_encode([]);
            $activation->status = 'active';
            $activation->save();

            sendNewBotActivationMail($activation);
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Bot activation";
            $notification->message = "Bot activated Successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Bot Activated Successfully',
                'data' => [
                    'activation' => $activation,
                    'user_balance' => $debit->balance
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to activate bot',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get bot details
     * @param int $id
     * @return JsonResponse
     */
    public function show($id): JsonResponse
    {
        try {
            $bot = Bot::find($id);

            if (!$bot) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Bot not found'
                ], 404);
            }

            return response()->json([
                'status' => 'success',
                'data' => [
                    'bot' => $bot
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch bot details',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get bot activations for user
     * @return JsonResponse
     */
    public function activations(): JsonResponse
    {
        try {
            $user = auth()->user();

            $activations = $user->botActivations()
                ->with('bot')
                ->orderBy('id', 'DESC')
                ->get();

            return response()->json([
                'status' => 'success',
                'data' => [
                    'activations' => $activations
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch activations',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get bot history for user
     * @return JsonResponse
     */
    public function history(): JsonResponse
    {
        try {
            $user = auth()->user();

            $histories = $user->botHistory()
                ->with(['botActivation.bot'])
                ->orderBy('timestamp', 'DESC')
                ->get();

            return response()->json([
                'status' => 'success',
                'data' => [
                    'histories' => $histories
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch bot history',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
