<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Models\BotActivation;
use App\Models\BotHistory;
use App\Models\Deposit;
use App\Models\User;
use App\Models\SharePlan;
use App\Models\MerchantPlan;
use App\Models\Withdrawal;
use App\Models\Transaction;
use App\Models\P2pTransfer;
use App\Models\Plan;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Validator;

class DashboardApiController extends Controller
{
    /**
     * Get admin dashboard statistics
     */
public function dashboard()
{
    try {
        $currencies = ['usd', 'ngn', 'kes'];

        // =======================
        // PRE-LOAD COMMON QUERIES
        // =======================
        $bots_count = BotHistory::count();
        $total_profit = BotHistory::sum('profit');
        $total_profit_percent = BotHistory::sum('profit_percent');

        $avg_profit = $bots_count > 0 ? $total_profit / $bots_count : 0;
        $avg_profit_percentage = $bots_count > 0 ? ($total_profit_percent / $bots_count) * 100 : 0;

        // =======================
        // USERS
        // =======================
        $stats['users'] = [
            'total' => User::count(),
            'active' => User::where('status', 1)->count(),
            'verified' => User::whereNotNull('email_verified_at')->count(),
            'kyc_verified' => User::whereNotNull('kyc_verified_at')->count(),
            'with_usd_balances' => User::where('balance', '>', 0)->count(),
            'with_ngn_balances' => User::where('ngn_balance', '>', 0)->count(),
            'with_kes_balances' => User::where('kes_balance', '>', 0)->count(),
        ];

        // =======================
        // FINANCIAL
        // =======================
        $depositTotals = \DB::table('deposits')
            ->selectRaw('LOWER(type) as currency, SUM(amount) as total_amount, COUNT(*) as records')
            ->groupByRaw('LOWER(type)')
            ->get()
            ->keyBy('currency');

        $pendingDeposits = \DB::table('deposits')
            ->selectRaw('LOWER(type) as currency, SUM(amount) as amount, COUNT(*) as records')
            ->where('status', 'pending')
            ->groupByRaw('LOWER(type)')
            ->get()
            ->keyBy('currency');

        $total_deposits = [];
        $pending_deposits = [];
        foreach ($currencies as $c) {
            $dRow = $depositTotals->get($c);
            $pRow = $pendingDeposits->get($c);

            $total_deposits[$c] = [
                'amount' => number_format($dRow->total_amount ?? 0, 2, '.', ''),
                'records' => $dRow->records ?? 0,
            ];
            $pending_deposits[$c] = [
                'amount' => number_format($pRow->amount ?? 0, 2, '.', ''),
                'records' => $pRow->records ?? 0,
            ];
        }

        $withdrawalTotals = \DB::table('withdrawals')
            ->selectRaw('LOWER(currency) as currency, SUM(amount) as total_amount, COUNT(*) as records')
            ->groupByRaw('LOWER(currency)')
            ->get()
            ->keyBy('currency');

        $pendingWithdrawals = \DB::table('withdrawals')
            ->selectRaw('LOWER(currency) as currency, SUM(amount) as amount, COUNT(*) as records')
            ->where('status', 'pending')
            ->groupByRaw('LOWER(currency)')
            ->get()
            ->keyBy('currency');

        $total_withdrawals = [];
        $pending_withdrawals = [];
        foreach ($currencies as $c) {
            $wRow = $withdrawalTotals->get($c);
            $pwRow = $pendingWithdrawals->get($c);

            $total_withdrawals[$c] = [
                'amount' => number_format($wRow->total_amount ?? 0, 2, '.', ''),
                'records' => $wRow->records ?? 0,
            ];
            $pending_withdrawals[$c] = [
                'amount' => number_format($pwRow->amount ?? 0, 2, '.', ''),
                'records' => $pwRow->records ?? 0,
            ];
        }

        // ----- BALANCES
        $stats['financial'] = [
            'total_deposits' => $total_deposits,
            'pending_deposits' => $pending_deposits,
            'total_withdrawals' => $total_withdrawals,
            'pending_withdrawals' => $pending_withdrawals,

            'usd_balances' => [
                'amount' => number_format(User::sum('balance'), 2, '.', ''),
                'records' => User::where('balance', '>', 0)->count(),
            ],
            'ngn_balances' => [
                'amount' => number_format(User::sum('ngn_balance'), 2, '.', ''),
                'records' => User::where('ngn_balance', '>', 0)->count(),
            ],
            'kes_balances' => [
                'amount' => number_format(User::sum('kes_balance'), 2, '.', ''),
                'records' => User::where('kes_balance', '>', 0)->count(),
            ],
            
            'cbc_balances' => [
                'amount' => number_format(User::sum('coin_balance'), 2, '.', ''),
                'usd_eq' => number_format(User::sum('coin_balance')*5.931, 2, '.', ''),
                'records' => User::where('coin_balance', '>', 0)->count(),
            ],

            'recent_deposits' => Deposit::with('user')->latest()->take(5)->get(),
            'recent_withdrawals' => Withdrawal::with('user')->latest()->take(5)->get(),
        ];

        // =======================
        // MINING
        // =======================
        $stats['mining'] = [
            'active_bots' => BotActivation::where('status', 'active')->count(),
            'total_capital' => number_format(BotHistory::sum('capital'), 2, '.', ''),
            'total_bots_history' => $bots_count,
            'total_profits' => number_format($total_profit, 2, '.', ''),
            'avg_profit' => number_format($avg_profit, 2, '.', ''),
            'avg_profit_percentage' => number_format($avg_profit_percentage, 2, '.', ''),
            'active_plans' => Plan::where('status', 1)->count(),
            'recent_activations' => BotActivation::with('user')->latest()->take(5)->get(),
        ];

        // =======================
        // TRANSACTIONS
        // =======================
        $stats['transactions'] = [
            'today' => Transaction::whereDate('created_at', today())->count(),
            'this_month' => Transaction::whereMonth('created_at', now()->month)->count(),
            'total' => Transaction::count(),
            'recent' => Transaction::with('user')->latest()->take(5)->get(),
        ];

        // =======================
        // GRAPH DATA — 30 DAYS
        // =======================
        $start = now()->subDays(29)->startOfDay();
        $end = now()->endOfDay();

        $days = collect(range(0, 29))
            ->map(fn($i) => now()->subDays($i)->format('Y-m-d'))
            ->reverse()
            ->values();

        $zeroSeries = $days->mapWithKeys(fn($d) => [$d => number_format(0, 2, '.', '')])->toArray();

        $deposits_last_30_days = [];
        $withdrawals_last_30_days = [];
        $transactions_last_30_days = [];

        foreach ($currencies as $c) {
            $deposits_last_30_days[$c] = $zeroSeries;
            $withdrawals_last_30_days[$c] = $zeroSeries;
            $transactions_last_30_days[$c] = $zeroSeries;
        }

        // DEPOSITS GRAPH
        $deposits = \DB::table('deposits')
            ->selectRaw('DATE(created_at) as date, LOWER(type) as currency, SUM(amount) as total_amount')
            ->whereBetween('created_at', [$start, $end])
            ->groupByRaw('DATE(created_at), LOWER(type)')
            ->get();

        foreach ($deposits as $row) {
            if (in_array($row->currency, $currencies)) {
                $deposits_last_30_days[$row->currency][$row->date] = number_format($row->total_amount, 2, '.', '');
            }
        }

        // WITHDRAWALS GRAPH
        $withdrawals = \DB::table('withdrawals')
            ->selectRaw('DATE(created_at) as date, LOWER(currency) as currency, SUM(amount) as total_amount')
            ->whereBetween('created_at', [$start, $end])
            ->groupByRaw('DATE(created_at), LOWER(currency)')
            ->get();

        foreach ($withdrawals as $row) {
            if (in_array($row->currency, $currencies)) {
                $withdrawals_last_30_days[$row->currency][$row->date] = number_format($row->total_amount, 2, '.', '');
            }
        }

        // TRANSACTIONS GRAPH (currency)
        $transactions = \DB::table('transactions')
            ->selectRaw('DATE(created_at) as date, LOWER(currency) as currency, COUNT(*) as total_count')
            ->whereBetween('created_at', [$start, $end])
            ->groupByRaw('DATE(created_at), LOWER(currency)')
            ->get();

        foreach ($transactions as $row) {
            if (in_array($row->currency, $currencies)) {
                $transactions_last_30_days[$row->currency][$row->date] = $row->total_count;
            }
        }

        $graph = [
            'financial' => [
                'deposits_last_30_days' => $deposits_last_30_days,
                'withdrawals_last_30_days' => $withdrawals_last_30_days,
            ],
            'users' => [
                'registrations_last_30_days' => $days->mapWithKeys(fn($d) => [
                    $d => User::whereDate('created_at', $d)->count()
                ]),
            ],
            'bots' => [
                'activations_last_30_days' => $days->mapWithKeys(fn($d) => [
                    $d => BotActivation::whereDate('created_at', $d)->count()
                ]),
            ],
            'transactions' => [
                'transactions_last_30_days' => $transactions_last_30_days,
            ],
        ];

        return response()->json([
            'status' => 'success',
            'data' => $stats,
            'graph' => $graph
        ]);

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



    /**
     * Get marketplace plans
     */
    public function marketplacePlans()
    {
        try {
            $plans = MerchantPlan::orderBy('created_at', 'desc')->get();
            
            return response()->json([
                'status' => 'success',
                'data' => $plans
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch marketplace plans',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Store marketplace plan
     */
    public function storeMerchantPlan(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'description' => 'nullable|string',
                'price' => 'required|numeric|min:0',
                'commission_rate' => 'required|numeric|min:0|max:100',
                'features' => 'nullable|array',
                'is_active' => 'boolean',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $plan = MerchantPlan::create($validator->validated());

            return response()->json([
                'status' => 'success',
                'message' => 'Merchant plan created successfully',
                'data' => $plan
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to create merchant plan',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update marketplace plan
     */
    public function updateMerchantPlan(Request $request, $id)
    {
        try {
            $plan = MerchantPlan::findOrFail($id);

            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'description' => 'nullable|string',
                'price' => 'required|numeric|min:0',
                'commission_rate' => 'required|numeric|min:0|max:100',
                'features' => 'nullable|array',
                'is_active' => 'boolean',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $plan->update($validator->validated());

            return response()->json([
                'status' => 'success',
                'message' => 'Merchant plan updated successfully',
                'data' => $plan
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to update merchant plan',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete marketplace plan
     */
    public function deleteMerchantPlan($id)
    {
        try {
            $plan = MerchantPlan::findOrFail($id);
            $plan->delete();

            return response()->json([
                'status' => 'success',
                'message' => 'Merchant plan deleted successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to delete merchant plan',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get share plans
     */
    public function sharePlans()
    {
        try {
            $plans = SharePlan::orderBy('created_at', 'desc')->get();
            
            return response()->json([
                'status' => 'success',
                'data' => $plans
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch share plans',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Store share plan
     */
    public function storeSharePlan(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:150',
                'category' => 'required|string|max:100',
                'risk_level' => 'required|in:LOW,MEDIUM,HIGH',
                'description' => 'nullable|string',
                'share_price' => 'required|numeric|min:0',
                'dividend_yield' => 'required|numeric|min:0|max:100',
                'frequency' => 'required|in:MONTHLY,QUARTERLY,BI-ANNUALLY,ANNUALLY',
                'min_investment' => 'required|numeric|min:0',
                'target_amount' => 'required|numeric|min:0',
                'raised_amount' => 'nullable|numeric|min:0',
                'funding_progress' => 'nullable|numeric|min:0|max:100',
                'investors_count' => 'nullable|integer|min:0',
                'rating' => 'nullable|numeric|min:0|max:5',
                'next_payout_date' => 'nullable|date',
                'is_active' => 'boolean',
                'image' => 'nullable|string', // For API, handle as base64 or URL
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $plan = SharePlan::create($validator->validated());

            return response()->json([
                'status' => 'success',
                'message' => 'Share plan created successfully',
                'data' => $plan
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to create share plan',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update share plan
     */
    public function updateSharePlan(Request $request, $id)
    {
        try {
            $plan = SharePlan::findOrFail($id);

            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:150',
                'category' => 'required|string|max:100',
                'risk_level' => 'required|in:LOW,MEDIUM,HIGH',
                'description' => 'nullable|string',
                'share_price' => 'required|numeric|min:0',
                'dividend_yield' => 'required|numeric|min:0|max:100',
                'frequency' => 'required|in:MONTHLY,QUARTERLY,BI-ANNUALLY,ANNUALLY',
                'min_investment' => 'required|numeric|min:0',
                'target_amount' => 'required|numeric|min:0',
                'raised_amount' => 'nullable|numeric|min:0',
                'funding_progress' => 'nullable|numeric|min:0|max:100',
                'investors_count' => 'nullable|integer|min:0',
                'rating' => 'nullable|numeric|min:0|max:5',
                'next_payout_date' => 'nullable|date',
                'is_active' => 'boolean',
                'image' => 'nullable|string',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $plan->update($validator->validated());

            return response()->json([
                'status' => 'success',
                'message' => 'Share plan updated successfully',
                'data' => $plan
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to update share plan',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete share plan
     */
    public function deleteSharePlan($id)
    {
        try {
            $plan = SharePlan::findOrFail($id);
            $plan->delete();

            return response()->json([
                'status' => 'success',
                'message' => 'Share plan deleted successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to delete share plan',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}