<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Http\Requests\User\SendThankCardRequest;
use App\Http\Requests\User\UpdateProfileRequest;
use App\Http\Requests\User\UpdatePasswordRequest;
use App\DTOs\DashboardDataDto;
use App\Exceptions\ThankCardException;
use App\Services\User\Contracts\UserServiceInterface;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class UserController extends Controller
{
    public function __construct(
        private readonly UserServiceInterface $userService
    ) {}

    /**
     * Display the user dashboard with transaction history, stats, and rankings.
     */
    public function index(Request $request): View
    {
        $selectedMonth = (string) $request->input('month', Carbon::now()->format('Y-m'));
        $user          = Auth::user();

        $administrations = $this->userService->getDashboard($user, $selectedMonth);

        $isAdmin = $user->role == config('constants.ROLE_ADMIN');

        if ($isAdmin) {
            $stats           = $this->userService->getPersonalStats($user, $selectedMonth);
            $receivedRanking = $this->userService->getRankingList('received', $selectedMonth, $user);
            $sentRanking     = $this->userService->getRankingList('sent', $selectedMonth, $user);

            $receivedCount               = (int) $stats['receivedCount'];
            $sentCount                   = (int) $stats['sentCount'];
            $currentRank                 = (int) $stats['currentRank'];
            $receivedRankers             = $receivedRanking['rankers'];
            $receivedCurrentUserRankItem = $receivedRanking['currentUserRankItem'];
            $sentRankers                 = $sentRanking['rankers'];
            $sentCurrentUserRankItem     = $sentRanking['currentUserRankItem'];
        } else {
            // For member, do NOT fetch ranking lists or calculate rank to ensure security and improve DB performance
            $startOfMonth = Carbon::parse($selectedMonth)->startOfMonth();
            $endOfMonth   = Carbon::parse($selectedMonth)->endOfMonth();

            $receivedCount = (int) \App\Models\Administration::where('msnv', $user->msnv)
                ->whereBetween('date', [$startOfMonth, $endOfMonth])
                ->sum('received');

            $sentCount = (int) \App\Models\Administration::where('msnv', $user->msnv)
                ->whereBetween('date', [$startOfMonth, $endOfMonth])
                ->sum('sent');

            $currentRank                 = 0;
            $receivedRankers             = [];
            $receivedCurrentUserRankItem = null;
            $sentRankers                 = [];
            $sentCurrentUserRankItem     = null;
        }

        $dashboardData = new DashboardDataDto(
            administrations: $administrations,
            selectedMonth: $selectedMonth,
            user: $user,
            receivedRankers: $receivedRankers,
            receivedCurrentUserRankItem: $receivedCurrentUserRankItem,
            sentRankers: $sentRankers,
            sentCurrentUserRankItem: $sentCurrentUserRankItem,
            receivedCount: $receivedCount,
            sentCount: $sentCount,
            currentRank: $currentRank
        );

        return view('user.dashboard', $dashboardData->toArray());
    }

    /**
     * Show the form to send thank cards.
     */
    public function sendThankcards(): View
    {
        $users = $this->userService->getOtherActiveUsers(Auth::user());
        return view('user.send', compact('users'));
    }

    /**
     * Get statistics for a specific recipient.
     */
    public function getRecipientStats(Request $request): JsonResponse
    {
        $receiverMsnv = (string) $request->query('receiver');
        if (empty($receiverMsnv)) {
            return response()->json(['success' => false, 'message' => 'Receiver is required'], 400);
        }

        $sender = Auth::user();
        $sentCount = $this->userService->getSentCardsToUserThisMonth($sender, $receiverMsnv);

        return response()->json([
            'success' => true,
            'sent_count' => $sentCount,
        ]);
    }

    public function storeThankcards(SendThankCardRequest $request): JsonResponse
    {
        try {
            $this->userService->sendThankcards(
                Auth::user(),
                (string) $request->input('receiver'),
                (int) $request->input('amount'),
                (int) $request->input('template_id', 1)
            );
        } catch (ThankCardException $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 422);
        }

        $receiverUser = \App\Models\User::where('msnv', $request->input('receiver'))->first();

        // Send ChatOps notification from backend to avoid CORS issues
        $chatOpsUrl = config('constants.CHATOPS_API_URL');
        $chatOpsToken = config('constants.CHATOPS_API_TOKEN');

        if ($chatOpsUrl && $chatOpsToken && $receiverUser) {
            try {
                \Illuminate\Support\Facades\Http::timeout(5)->post($chatOpsUrl, [
                    'message' => "💌 Bạn nhận được một Thank Card mới!\nNhanh chân đến khu vực nhận thư để nhận ngay nhé!",
                    'userEmail' => $receiverUser->mail,
                    'token' => $chatOpsToken,
                ]);
            } catch (\Exception $e) {
                \Illuminate\Support\Facades\Log::error('ChatOps API failed: ' . $e->getMessage());
            }
        }

        $sender = Auth::user();
        $newRecipientSentCount = $this->userService->getSentCardsToUserThisMonth($sender, (string) $request->input('receiver'));

        return response()->json([
            'success' => true,
            'message' => __('messages.thank_card_send_success'),
            'receiver_email' => $receiverUser ? $receiverUser->mail : '',
            'new_balance' => (int) $sender->card,
            'new_recipient_sent_count' => $newRecipientSentCount,
        ]);
    }

    // New page: list of ThankCards received by the current user
    public function receivedCards(Request $request)
    {
        $selectedMonth = $request->input('month', Carbon::now()->format('Y-m'));
        $user = Auth::user();
        
        if ($request->ajax() || $request->wantsJson()) {
            $offset = (int) $request->input('offset', 0);
            $limit = 12;
            $data = $this->userService->getReceivedPageData($user, $selectedMonth, $limit, $offset);
            
            $html = view('user.partials.received_cards_feed', ['cards' => $data['cards']])->render();
            return response()->json([
                'success' => true,
                'html' => $html,
                'hasMore' => $data['hasMore'],
                'totalCards' => $data['totalCards'],
                'totalSenders' => $data['totalSenders']
            ]);
        }
        
        $data = $this->userService->getReceivedPageData($user, $selectedMonth, 12, 0);
        $data['selectedMonth'] = $selectedMonth;
        return view('user.received', $data);
    }

    // New page: list of ThankCards sent by the current user
    public function sentCards(Request $request)
    {
        $selectedMonth = $request->input('month', Carbon::now()->format('Y-m'));
        $user = Auth::user();
        
        if ($request->ajax() || $request->wantsJson()) {
            $offset = (int) $request->input('offset', 0);
            $limit = 12;
            $data = $this->userService->getSentPageData($user, $selectedMonth, $limit, $offset);
            
            $html = view('user.partials.sent_cards_feed', ['cards' => $data['cards']])->render();
            return response()->json([
                'success' => true,
                'html' => $html,
                'hasMore' => $data['hasMore'],
                'totalCards' => $data['totalCards'],
                'totalReceivers' => $data['totalReceivers']
            ]);
        }
        
        $data = $this->userService->getSentPageData($user, $selectedMonth, 12, 0);
        $data['selectedMonth'] = $selectedMonth;
        return view('user.sent', $data);
    }

    // New page: ranking (both received and sent) with tabs
    public function ranking(Request $request): \Illuminate\View\View
    {
        if (Auth::user()->role !== config('constants.ROLE_ADMIN')) {
            abort(404);
        }

        $selectedMonth = $request->input('month', Carbon::now()->format('Y-m'));
        $user = Auth::user();
        $receivedRanking = $this->userService->getRankingList('received', $selectedMonth, $user);
        $sentRanking = $this->userService->getRankingList('sent', $selectedMonth, $user);
        return view('user.ranking', [
            'selectedMonth' => $selectedMonth,
            'receivedRankers' => $receivedRanking['rankers'],
            'receivedCurrentUserRankItem' => $receivedRanking['currentUserRankItem'],
            'sentRankers' => $sentRanking['rankers'],
            'sentCurrentUserRankItem' => $sentRanking['currentUserRankItem'],
        ]);
    }


    /**
     * Show the change password form.
     */
    public function changePasswordForm(): View
    {
        return view('user.change_password');
    }

    /**
     * Handle user password change.
     */
    public function updatePassword(UpdatePasswordRequest $request): RedirectResponse
    {
        $user = Auth::user();
        $this->userService->updatePassword($user, $request->input('password'));

        $route = $user->role == config('constants.ROLE_ADMIN') ? 'admin.dashboard' : 'user.dashboard';
        return redirect()->route($route)->with('success', __('messages.password_change_success'));
    }

    /**
     * Show the edit profile page (avatar & password).
     */
    public function editProfile(): View
    {
        return view('user.edit');
    }

    /**
     * Handle avatar upload and optional password change.
     */
    public function updateProfile(UpdateProfileRequest $request): RedirectResponse
    {
        $user = Auth::user();

        $this->userService->updateProfile(
            $user,
            $request->validated(),
            $request->file('avatar')
        );

        return redirect()->route('user.edit')->with('success', 'Cập nhật hồ sơ thành công');
    }
}
