<?php

namespace App\Http\Controllers;

use App\Models\Trader;
use App\Models\Trade;
use App\Models\Copier;
use Illuminate\Http\Request;
use Cloudinary;

class TraderController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    public function genrateNum($min, $max, $step){
        $range = range($min, $max, $step);
        $random = collect($range)->shuffle()->slice(0, 1);
        $earned_percent = $random[0];

        return $earned_percent;
    }

    private function parseNullableValue($value) {
        // Handle various forms of null/empty values from frontend
        if (is_null($value) || $value === '' || $value === 'null' || $value === 'undefined') {
            return null;
        }
        return $value;
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $faker = \Faker\Factory::create();

        $leverage1 = $this->genrateNum(50, 900, 50);
        
        $levels = ['Legend', 'Growing Talent', 'Expert', 'High Achiever'];

        $random  = array_rand($levels);
        $trader = new Trader;
        $trader->trader_name = $faker->userName();
        $trader->level = $levels[$random];
        $trader->min_amount = $this->genrateNum(10, 1000, 20);
        $trader->gain = $this->genrateNum(1, 100, 8.7);
        $trader->copiers = $this->genrateNum(1, 100000, 20);
        $trader->commission = $this->genrateNum(1, 100, 5);
        $trader->profit = $this->genrateNum(10, 1000000, 50);
        $trader->loss = $this->genrateNum(10, 1000000, 50);
        $trader->risk_score = $this->genrateNum(1, 6, 1);
        $trader->equity = $this->genrateNum(10, 1000000, 10);
        $trader->duration = $this->genrateNum(10, 1000, 25);
        $trader->description = $faker->text();
        $trader->floating_profit = $this->genrateNum(10, 1000000, 50);
        $trader->balance = $this->genrateNum(10, 1000000, 20);
        $trader->master_traders_bonus = $this->genrateNum(10, 10000, 27);
        $trader->leverage = "1:$leverage1";
        $trader->max_unrealised_loss = $this->genrateNum(10, 1000000, 50);
        $trader->max_drawdown_duration = $this->genrateNum(10, 1000, 25);
        $trader->image = $faker->imageUrl();
        $trader->save();
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Trader  $trader
     * @return \Illuminate\Http\Response
     */
    public function show(Trader $trader)
    {
        $traders = Trader::orderByDesc('id')->take(150)->get()->load(['trades', 'followers']);
        return response()->json([
            'status' => 'success',
            'message' => 'traders loaded successfully',
            'traders' => $traders
        ], 200);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Trader  $trader
     * @return \Illuminate\Http\Response
     */
    public function edit(Trader $trader, $id)
    {
        $trader = $trader->find($id);
        if (!$trader) {
           return response()->json([
            'status' => 'error',
            'message' => 'failed to load trader'
           ], 400);
        }

        return response()->json([
            'status' => 'success',
            'message' => 'loaded',
            'trader' => $trader
        ], 200);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Trader  $trader
     * @return \Illuminate\Http\Response
     */
    public function saveTrader(Request $request)
    {
        $request->validate([
            'trader_name' => 'required',
            'level' => 'required',
            'min_amount' => 'required',
            'gain' => 'required',
            'copiers' => 'required',
            'profit' => 'required',
            'loss' => 'required',
            'risk_score' => 'required',
            'duration' => 'required',
            'image' => 'required',
        ]);


        $image = Cloudinary::upload($request->file('image')->getRealPath())->getSecurePath();
        $trader = new Trader;
        $trader->trader_name = $request->trader_name;	
        $trader->level = $request->level;	
        $trader->min_amount = $request->min_amount;	
        $trader->gain = $request->gain;	
        $trader->copiers = $request->copiers;	
        $trader->commission = $request->commission;	
        $trader->profit = $request->profit;	
        $trader->loss = $request->loss;	
        $trader->risk_score = $request->risk_score;	
        $trader->equity = $request->equity;	
        $trader->duration = $request->duration;	
        $trader->description = $request->description;	
        $trader->floating_profit = $request->floating_profit;	
        $trader->balance = $request->balance;	
        $trader->master_traders_bonus = $request->master_traders_bonus;	
        $trader->leverage = $request->leverage;	
        $trader->max_unrealised_loss = $request->max_unrealised_loss;	
        $trader->max_drawdown_duration = $request->max_drawdown_duration;	
        $trader->image = $image;
        $trader->save();

        return response()->json([
            'status' => 'success',
            'message' => 'traders created successfully',
        ], 200);

    }

    public function update(Request $request){

        $request->validate([
            'trader_id' => 'required',
            'trader_name' => 'required',
            'level' => 'required',
            'min_amount' => 'required',
            'gain' => 'required',
            'copiers' => 'required',
            'commission' => 'nullable',
            'profit' => 'required',
            'loss' => 'required',
            'risk_score' => 'required',
            'equity' => 'nullable',
            'duration' => 'required',
            'description' => 'nullable',
            'floating_profit' => 'nullable',
            'balance' => 'nullable',
            'master_traders_bonus' => 'nullable',
            'leverage' => 'nullable',
            'max_unrealised_loss' => 'nullable',
            'max_drawdown_duration' => 'nullable',
        ]);

        $trader = Trader::find($request->trader_id);
        if (!$trader) {
            return response()->json([
                'status' => 'error',
                'message' => 'Trader not found with ID: ' . $request->trader_id
            ], 404);
        }
        $image = $trader->image;
        if ($request->hasFile('image') && $request->file('image')->isValid()) {
            $image = Cloudinary::upload($request->file('image')->getRealPath())->getSecurePath();
        }

        $trader->trader_name = $request->trader_name;	
        $trader->level = $request->level;	
        $trader->min_amount = $request->min_amount;	
        $trader->gain = $request->gain;	
        $trader->copiers = $request->copiers;	
        $trader->commission = $this->parseNullableValue($request->commission);	
        $trader->profit = $request->profit;	
        $trader->loss = $request->loss;	
        $trader->risk_score = $request->risk_score;	
        $trader->equity = $this->parseNullableValue($request->equity);	
        $trader->duration = $request->duration;	
        $trader->description = $this->parseNullableValue($request->description);	
        $trader->floating_profit = $this->parseNullableValue($request->floating_profit);	
        $trader->balance = $this->parseNullableValue($request->balance);	
        $trader->master_traders_bonus = $this->parseNullableValue($request->master_traders_bonus);	
        $trader->leverage = $this->parseNullableValue($request->leverage);	
        $trader->max_unrealised_loss = $this->parseNullableValue($request->max_unrealised_loss);	
        $trader->max_drawdown_duration = $this->parseNullableValue($request->max_drawdown_duration);	
        $trader->image = $image;
        $trader->save();

        return response()->json([
            'status' => 'success',
            'message' => 'Trader "' . $trader->trader_name . '" updated successfully',
            'trader' => $trader
        ], 200);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Trader  $trader
     * @return \Illuminate\Http\Response
     */
    public function destroy(Trader $trader, $id)
    {
        $traderToDelete = $trader->find($id);
        if (!$traderToDelete) {
            return response()->json([
                'status' => 'error',
                'message' => 'Trader not found!'
            ], 404);
        }

        // Check for existing trades and copiers that use this trader
        $tradesCount = $traderToDelete->trades()->count();
        $copiersCount = $traderToDelete->followers()->count();
        $totalRelated = $tradesCount + $copiersCount;
        
        if ($totalRelated > 0) {
            // Find an alternative trader to reassign trades and copiers
            $alternativeTrader = Trader::where('id', '!=', $id)
                ->where('level', $traderToDelete->level)
                ->first();

            if (!$alternativeTrader) {
                // If no exact match, find any trader
                $alternativeTrader = Trader::where('id', '!=', $id)->first();
            }

            if (!$alternativeTrader) {
                return response()->json([
                    'status' => 'error',
                    'message' => "Cannot delete trader. {$tradesCount} trade(s) and {$copiersCount} copier(s) are using this trader and no alternative trader found. Please create another trader first."
                ], 400);
            }

            // Update all trades and copiers to use the alternative trader
            $traderToDelete->trades()->update(['trader_id' => $alternativeTrader->id]);
            $traderToDelete->followers()->update(['trader_id' => $alternativeTrader->id]);
            
            $message = "Trader deleted successfully. {$tradesCount} trade(s) and {$copiersCount} copier(s) have been reassigned to {$alternativeTrader->trader_name}.";
        } else {
            $message = "Trader deleted successfully.";
        }

        // Delete the trader
        $traderToDelete->delete();

        return response()->json([
            'status' => 'success',
            'message' => $message
        ], 200);
    }
}
