<?php

namespace App\Http\Controllers\Client;

use App\Events\ClientTeamPaymentCompleted;
use App\Events\TeamPaymentCompleted;
use App\Http\Controllers\Controller;
use App\Mail\TeamInvitationMail;
use App\Mail\RosterConfirmationMail;
use Illuminate\Support\Arr; // Add this import for array_flatten replacement
use App\Models\ClientDetail;
use App\Models\Page;
use App\Models\Question;
use App\Models\QuestionBank;
use App\Models\Team;
use App\Models\TeamAddonItem;
use App\Models\TeamContract;
use App\Models\TeamDoc;
use App\Models\TeamMember;
use App\Models\TeamPaymentSchedule;
use App\Models\TeamQuestionOption;
use App\Models\TeamRegistrationQuestion;
use App\Models\TeamSaleItem;
use App\Models\TeamsDocRequest;
use App\Models\TeamUserAnswer;
use App\Models\TeamUserInsuranceDetail;
use App\Models\TeamUserPaymentsSchedule;
use App\Models\TeamUserRegistrationCardDetail;
use App\Models\TeamUserRegistrationContact;
use App\Models\TeamUserRegistrationDetail;
use App\Services\IPOSpaysService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Mail;
use Yajra\DataTables\DataTables;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use App\Services\VerticalInsureService;



class TeamController extends Controller
{

    // Team List
    public function teamList(Request $request)
    {
        $userId = auth()->user()->id;
        // $teams = Team::select('teams.*', 'team_user_registration_details.term_accept')
        //     ->join('team_user_registration_details', 'teams.id', '=', 'team_user_registration_details.team_id')
        //     ->where('team_user_registration_details.user_id', $userId)
        //     ->whereNull('team_user_registration_details.deleted_at')
        //     ->with('trainer') // Eager load related trainer data
        //     ->get();
        $mainUser = ClientDetail::where('user_id', $userId)->value('house_hold_user_id');

        // Fetch household users invited by the main user
        //$households = TeamUserRegistrationDetail::where('invite_by', $mainUser)->pluck('user_id')->toArray();

        $households = TeamUserRegistrationDetail::where('invite_by', $mainUser)
            ->where('term_accept', 1)
            ->where('user_id', $userId)
            ->pluck('user_id')->toArray();
        // dd($households);
        // Combine the authenticated user ID with household user IDs
        $userIds = array_merge([$userId], $households);

        // Query teams for the authenticated user and household users
        $teams = Team::select('teams.*', 'team_user_registration_details.term_accept')
            ->join('team_user_registration_details', 'teams.id', '=', 'team_user_registration_details.team_id')
            ->whereIn('team_user_registration_details.user_id', $userIds)
            ->whereNull('team_user_registration_details.deleted_at')
            ->with('trainer') // Eager load related trainer data
            ->get();

        info($userId);
        info($teams);
        if ($request->ajax()) {
            return DataTables::of($teams)
                ->addIndexColumn()
                ->addColumn('team_name', function ($team) {
                    switch ($team->term_accept) {
                        case 1:
                            $badgeText = 'Accept';
                            $badgeClass = 'bg-success';
                            break;
                        case 2:
                            $badgeText = 'Rejected';
                            $badgeClass = 'bg-danger';
                            break;
                        case 0:
                        default:
                            $badgeText = 'Pending';
                            $badgeClass = 'bg-warning';
                            break;
                    }

                    // Return the team name with the corresponding badge
                    return [
                        'name'  => $team->name,
                        'badge' => [
                            'text'  => $badgeText,
                            'class' => $badgeClass
                        ]
                    ];
                })
                ->addColumn('payment_action', function ($team) {
                    if ($team->term_accept == 1) {
                        $manageUrl = route('client.manage-reminder', $team->id);
                        return '<a href="' . $manageUrl . '" class="btn btn-primary text-black shadow-none text-decoration-none bg-skyblue">Manage Payment</a>';
                    } else {
                        return '-';
                    }
                    return '';
                })
                ->addColumn('team_action', function ($team) {
                    // Define the team action button (View Team)
                    $viewUrl = route('client.teams', ['teamSlug' => $team->team_slug]);
                    return '<a href="' . $viewUrl . '" class="btn btn-primary shadow-none text-decoration-none bg-blue" target="_blank">View Team</a>';
                })
                ->rawColumns(['team_name', 'payment_action', 'team_action']) // Mark these columns as containing raw HTML
                ->make(true);
        }
        return view('client.team.team-list', compact('teams'));
    }

    public function manageReminder($id, Request $request)
    {
        $userId = auth()->user()->id;

        $teamRegistrationDetails = TeamUserRegistrationDetail::where('team_id', $id)
            ->get();


        $team = Team::with(['trainer'])->findOrFail($id);
        $payment_report = TeamUserPaymentsSchedule::where('user_id', $userId)->where('team_id', $team->id)->get();

        // Decode JSON fields
        $saleItemIds = [];
        $addonItemIds = [];

        // Extract saleItemIds and addonItemIds from registration details
        foreach ($teamRegistrationDetails as $detail) {
            if ($detail->sales_items_id) {
                $saleItemIds[] = $detail->sales_items_id;
            }
            if ($detail->addon_items_ids) {
                $addonItemIds = array_merge($addonItemIds, json_decode($detail->addon_items_ids, true));
            }
        }

        $saleItems = TeamSaleItem::whereIn('id', $saleItemIds)->get(['name', 'price']);
        $addonItems = TeamAddonItem::whereIn('id', $addonItemIds)->get(['name', 'price']);

        $totalAmount = collect($saleItems)->sum('price') + collect($addonItems)->sum('price');

        $data = [
            'id' => $id,
            'name' => $team->name,
            'tag' => $team->tag,
            'trainer_name' => $team->trainer ? $team->trainer->name : 'N/A',
            'payment_schedules' => $payment_report->map(function ($schedule) {
                return [
                    'installment_number' => $schedule->installment,
                    'amount' => $schedule->amount,
                    'status' => $schedule->status,
                    'transaction_id' => $schedule->transactionId,
                    'due_date' => $schedule->next_payment_schedule,
                ];
            }),
            'sale_items' => $saleItems, // Add sale item names
            'addon_items' => $addonItems, // Add addon item names
            'total_amount' => $totalAmount,
            'payment_dates' => [
                'start_date' => $team->payment_start_date,
                'end_date' => $team->payment_end_date,
            ],
        ];


        // Step 1: Get all household clients
        $householdClients = ClientDetail::with(['countryName', 'stateName', 'cityName', 'user'])
            ->where('house_hold_user_id', auth()->user()->id)
            ->get();

        // Step 2: Filter clients whose user_id exists in team_user_registration_details
        $clientDetails = $householdClients->filter(function ($client) use ($id) {
            return DB::table('team_user_registration_details')
                ->join('users', 'team_user_registration_details.user_id', '=', 'users.id')
                ->where('team_user_registration_details.user_id', $client->user_id)
                ->where('team_user_registration_details.team_id', $id)
                ->where('team_user_registration_details.invite_by', auth()->user()->id)
                ->whereNull('team_user_registration_details.deleted_at')
                ->exists();
        });


        $teamUserDetails = TeamUserRegistrationDetail::where('user_id', $userId)->get();

        $teams_list_details = Team::whereIn('id', $teamUserDetails->pluck('team_id'))->get();
        return view('client.manage-reminder', compact('data', 'clientDetails', 'teams_list_details'));
    }

    public function print($id, Request $request)
    {
        $teamRegistrationDetails = TeamUserRegistrationDetail::where('team_id', $id)
            ->get();
        $userId = auth()->user()->id;

        // Fetch the specific team by its id
        $team = Team::with(['trainer'])->findOrFail($id);
        $payment_report = TeamUserPaymentsSchedule::where('user_id', $userId)->where('team_id', $team->id)->get();
        // Decode JSON fields
        $saleItemIds = [];
        $addonItemIds = [];

        // Extract saleItemIds and addonItemIds from registration details
        foreach ($teamRegistrationDetails as $detail) {
            if ($detail->sales_items_id) {
                $saleItemIds[] = $detail->sales_items_id;
            }
            if ($detail->addon_items_ids) {
                $addonItemIds = array_merge($addonItemIds, json_decode($detail->addon_items_ids, true));
            }
        }

        $saleItems = TeamSaleItem::whereIn('id', $saleItemIds)->get(['name', 'price']);
        $addonItems = TeamAddonItem::whereIn('id', $addonItemIds)->get(['name', 'price']);
        $totalAmount = collect($saleItems)->sum('price') + collect($addonItems)->sum('price');

        $data = [
            'id' => $id,
            'name' => $team->name,
            'tag' => $team->tag,
            'trainer_name' => $team->trainer ? $team->trainer->name : 'N/A',
            'payment_schedules' => $payment_report->map(function ($schedule) {
                return [
                    'installment_number' => $schedule->installment,
                    'amount' => $schedule->amount,
                    'status' => $schedule->status,
                    'transaction_id' => $schedule->transactionId,
                    'due_date' => $schedule->next_payment_schedule,
                ];
            }),
            'sale_items' => $saleItems, // Add sale item names
            'addon_items' => $addonItems, // Add addon item names
            'total_amount' => $totalAmount,
            'payment_dates' => [
                'start_date' => $team->payment_start_date,
                'end_date' => $team->payment_end_date,
            ],
        ];


        $safeFileName = preg_replace('/[\/\\\\]/', '_', $team->name) . '.pdf';

        $pdf = Pdf::loadView('client.print', compact('data'));

        return $pdf->download($safeFileName);
    }

    public function index($teamSlug)
    {

        $teamDetails = Team::where('team_slug', $teamSlug)->firstOrFail();
        $insuranceDetail = TeamUserInsuranceDetail::where('team_id', $teamDetails->id)
            ->where('user_id', auth()->id())
            ->first();

        // Retrieve household members who have not yet been invited by the authenticated user
        $nonInvitedHouseHoldList = ClientDetail::where('house_hold_user_id', auth()->id())
            ->whereDoesntHave('teamUserRegistrationDetails', function ($query) use ($teamDetails) {
                $query->where('team_id', $teamDetails->id)
                    ->where('invite_by', auth()->id());
            })
            ->get();

        // Retrieve household members who have already been invited by the authenticated user
        $invitedHouseHoldList = ClientDetail::where('house_hold_user_id', auth()->id())
            ->whereHas('teamUserRegistrationDetails', function ($query) use ($teamDetails) {
                $query->where('team_id', $teamDetails->id)
                    ->where('invite_by', auth()->id());
            })
            ->get();

        // Retrieve the user acceptance status
        $userAcceptanceStatus = TeamUserRegistrationDetail::where('team_id', $teamDetails->id)
            ->where('user_id', auth()->id())
            ->value('term_accept');

        // Retrieve accepted contract IDs for the authenticated user
        $acceptedContractIds = TeamUserRegistrationContact::where('team_id', $teamDetails->id)
            ->where('user_id', auth()->id())
            ->pluck('contract_id')
            ->toArray();


        // Retrieve team contracts and mark accepted ones
        $teamContracts = TeamContract::where('team_id', $teamDetails->id)->orderBy('contract_value', 'asc')
            ->get();
        $contracts = $teamContracts->map(function ($contract) use ($acceptedContractIds) {
            $page = Page::find($contract->contract_id);
            return [
                'id' => $contract->id,
                'contract_id' => $contract->contract_id,
                'title' => $page ? $page->title : 'No Title',
                'slug' => $page ? $page->slug : null,
                'accepted' => in_array($contract->contract_id, $acceptedContractIds), // Mark as accepted
            ];
        });
        $questionBank = QuestionBank::with('questions.answers')->where('id', $teamDetails->team_question_id)->firstOrFail();
        $existingAnswers = TeamUserAnswer::where('team_id', $teamDetails->id)
            ->where('user_id', Auth::id())
            ->pluck('answer', 'question_id');
        // Decode the sale_item_ids stored in the team record (assuming JSON format)
        $saleItemIds = json_decode($teamDetails->sale_item_ids, true);

        $mandatorySaleItemIds = json_decode($teamDetails->mandatory_sale_item_ids, true);

        // Fetch active sales items that match the IDs in mandatory_sale_item_ids
        $mandatorySalesItems = TeamSaleItem::whereIn('id', $mandatorySaleItemIds)
            ->where('status', 'active')
            ->get();

        // Fetch active sales items that match the IDs in sale_item_ids, excluding mandatory items
        $salesItems = TeamSaleItem::whereIn('id', $saleItemIds)
            ->where('status', 'active')
            ->whereNotIn('id', $mandatorySaleItemIds)
            ->get();

        $selectedSaleItemId = TeamUserRegistrationDetail::where('team_id', $teamDetails->id)
            ->where('user_id', auth()->id())
            ->value('sales_items_id');

        $addonItemIds = json_decode($teamDetails->addon_items_ids, true) ?? []; // Default to an empty array if null

        // Fetch only active addon items that match the IDs in addonItemIds if it's not empty
        $addonItems = TeamAddonItem::when(!empty($addonItemIds), function ($query) use ($addonItemIds) {
            return $query->whereIn('id', $addonItemIds);
        })
            ->where('status', 'active')
            ->get();

        // Retrieve selected addon item IDs from the user's registration details, defaulting to an empty array if null
        $selectedAddonItemIds = json_decode(TeamUserRegistrationDetail::where('team_id', $teamDetails->id)
            ->where('user_id', auth()->id())
            ->value('addon_items_ids'), true) ?? [];
        // Retrieve the record for a specific user and team
        $cardDetails = TeamUserRegistrationCardDetail::where('team_id', $teamDetails->id)
            ->where('user_id', auth()->id())
            ->first();


        // if ($cardDetails) {
        //     // Access the decrypted card details
        //     $decryptedCardDetails = $cardDetails->card_details;

        //     // Check if decryption was successful
        //     if ($decryptedCardDetails) {
        //         // Process the decrypted card details as needed
        //         // For example, display the card holder's name
        //         echo $decryptedCardDetails['card_holder_name'];
        //     } else {
        //         // Handle the case where decryption failed or data is null
        //         echo "Card details could not be decrypted.";
        //     }
        // } else {
        //     // Handle the case where no record was found
        //     echo "No card details found for the specified user and team.";
        // }

        // die;

        $paymentData = TeamUserPaymentsSchedule::where('user_id', Auth::id())
            ->where('team_id', $teamDetails->id)
            ->where('status', 'paid')
            ->orderBy('installment', 'desc')
            ->first();




        return view('client.team.index', compact(
            'teamDetails',
            'nonInvitedHouseHoldList',
            'invitedHouseHoldList',
            'userAcceptanceStatus',
            'contracts',
            'questionBank',
            'existingAnswers',
            'salesItems',
            'mandatorySalesItems',
            'selectedSaleItemId',
            'addonItems',
            'selectedAddonItemIds',
            'cardDetails',
            'paymentData',
            'insuranceDetail',

        ));
    }
    public function certificate($teamSlug, Request $request)
    {
        // Decrypt the ID from the query string
        $teamsDocRequestId = decrypt($request->query('id')); // Use query() to get the 'id' from the URL

        // Retrieve the data using the decrypted ID
        $teamMemberCertificate = TeamsDocRequest::find($teamsDocRequestId);

        if (!$teamMemberCertificate) {
            abort(404); // Handle the case where the ID doesn't exist
        }

        // Retrieve the team by teamSlug
        $team = Team::where('team_slug', $teamSlug)->firstOrFail();

        // Pass the necessary data to the Blade view
        return view('client.certificate.index', [
            'teamSlug' => $teamSlug,
            'teamName' => $team->name,  // Pass team name
            'teamId' => $team->id,      // Pass team ID
            'teamMemberCertificate' => $teamMemberCertificate,
        ]);
    }



    public function store_certificate(Request $request)
    {
        // Debugging: Uncomment to inspect the request data
        // dd($request->all());

        // Validate the form input
        $validator = Validator::make($request->all(), [
            'team_id' => 'required|exists:teams,id',
            'member_id' => 'required|exists:users,id',
            'teams_doc_request_id' => 'required|string',
            'file_name.*' => 'required|string|max:255', // Validate each file_name as an array
            'file_doc.*' => 'required|file|mimes:pdf,doc,docx|max:2048', // Validate each file_doc as an array
        ]);

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

        try {
            // Decrypt the teams_doc_request_id
            $teamsDocRequestId = decrypt($request->teams_doc_request_id);

            // Retrieve the certificate request record
            $teamMemberCertificate = TeamsDocRequest::find($teamsDocRequestId);

            if (!$teamMemberCertificate) {
                return response()->json([
                    'status' => false,
                    'message' => 'Invalid document request ID.'
                ], 404);
            }

            // Get the arrays of file names and files
            $fileNames = $request->input('file_name');
            $files = $request->file('file_doc');

            // Ensure the number of files matches the number of names
            if (count($fileNames) !== count($files)) {
                return response()->json([
                    'status' => false,
                    'message' => 'Mismatch between file names and uploaded files.'
                ], 422);
            }

            $uploadedDocs = [];

            // Process each file and its corresponding name
            foreach ($files as $index => $file) {
                // Store the file in storage/app/public/team_docs
                $filePath = $file->store('team_docs', 'public');

                // Save document details in the database
                $teamDoc = TeamDoc::create([
                    'team_id' => $request->team_id,
                    'member_id' => $request->member_id,
                    'file_name' => $fileNames[$index],
                    'file_doc' => $filePath,
                    'teams_doc_request_id' => $teamsDocRequestId,
                ]);

                $uploadedDocs[] = $teamDoc;
            }

            return response()->json([
                'status' => true,
                'message' => 'Documents uploaded successfully!',
                'data' => $uploadedDocs
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'File upload failed: ' . $e->getMessage()
            ], 500);
        }
    }





    public function create()
    {
        // Show form for creating a new team
    }
    public function store(Request $request)
    {
        // Handle the form submission to store a new team
    }
    public function show($id) {}

    public function edit($id)
    {
        // Show form for editing an existing team
    }

    public function update(Request $request, $id)
    {
        // Handle the form submission to update a team
    }

    public function destroy($id)
    {
        // Delete a team
    }
    // acceptTeam
    public function acceptTeam(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'user_id' => 'required|exists:users,id',
            'term_accept' => 'required|in:1,2', // 1 = Accept, 2 = Reject
        ]);

        try {
            // Update or create the registration detail
            TeamUserRegistrationDetail::updateOrCreate(
                ['team_id' => $request->team_id, 'user_id' => $request->user_id],
                ['term_accept' => $request->term_accept, 'invite_send' => $request->invite_send]
            );

            // If accepted, add the user to the team
            if ($request->term_accept == 1) {
                $addMemberResponse = $this->addMember($request);
                $addMemberResponse = json_decode($addMemberResponse->getContent(), true);



                if (!$addMemberResponse['status']) {
                    return response()->json($addMemberResponse, 400);
                }

                $this->sendRosterConfirmationEmail($request->user_id, $request->team_id);


                $message = 'You have successfully accepted the invitation and were added to the team.';
            } else {
                $message = 'You have declined the invitation.';
            }
            return $this->apiResponse($message, true, [], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('Failed to accept the team invitation.', false, [], 500);
        }
    }

    private function sendRosterConfirmationEmail($userId, $teamId)
    {
        try {
            // Get user details
            $user = \App\Models\User::find($userId);
            $clientDetail = ClientDetail::where('user_id', $userId)->first();

            // Get team details
            $team = Team::find($teamId);

            if ($user && $team) {
                $userName = $clientDetail ? $clientDetail->fullname : $user->name;
                $teamLink = route('client.teams', ['teamSlug' => $team->team_slug]);

                // Send the confirmation email
                Mail::to($user->email)->send(new RosterConfirmationMail($userName, $team->name, $teamLink));

                Log::info("Roster confirmation email sent successfully to user {$userId} ({$user->email}) for team '{$team->name}' (ID: {$teamId})");
            } else {
                Log::warning("Could not send roster confirmation email - User or Team not found. User ID: {$userId}, Team ID: {$teamId}");
            }
        } catch (\Exception $e) {
            Log::error("Failed to send roster confirmation email to user {$userId} for team {$teamId}: " . $e->getMessage());
            // Don't throw the exception to avoid breaking the main flow
            // The user registration should still succeed even if email fails
        }
    }

    // Add a new member to the team
    public function addMember(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
        ], [
            'team_id.required' => 'The team ID is required.',
            'team_id.exists' => 'The selected team ID does not exist.',
        ]);

        $teamId = $request->input('team_id');
        $user = Auth::user();
        $memberId = $user->id;
        $playerName = $user->name;

        // Check if the member already exists in the team
        $existingMember = TeamMember::where('team_id', $teamId)
            ->where('member_id', $memberId)
            ->first();

        if ($existingMember) {
            // Update the existing member's record
            $existingMember->update([
                'player_name' => $playerName, // Update player name if necessary
            ]);


            return $this->apiResponse('Your membership information has been updated successfully.', true, [], 200);
        }

        // Add the new member to the team
        TeamMember::create([
            'player_name' => $playerName,
            'team_id' => $teamId,
            'member_id' => $memberId,
        ]);

        return $this->apiResponse('You have been added to the team successfully.', true, [], 200);
    }

    // Remove a member from the team
    public function removeMember(Request $request, $teamId, $memberId)
    {
        try {
            // Find the team member to delete
            $teamMember = TeamMember::where('team_id', $teamId)
                ->where('member_id', $memberId)
                ->first();
            if (!$teamMember) {
                return $this->apiResponse('Team member not found.', false, [], 404);
            }
            // Delete the team member
            $teamMember->delete();
            return $this->apiResponse('Team member removed successfully.', true, [], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('Something went wrong.', false, [], 500);
        }
    }
    public function fetchMembers($teamId)
    {
        // Get members not in this team
        $members = User::whereHas('roles', function ($query) {
            $query->where('name', 'client');
        })
            ->whereNotIn('id', TeamMember::where('team_id', $teamId)->pluck('member_id'))
            ->get();
        return $this->apiResponse('Members retrieved successfully.', true, $members, 200);
    }
    public function inviteMember(Request $request)
    {
        // Validate the incoming request
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'user_id' => 'required|exists:users,id',
        ]);

        try {
            // Check if the user has accepted the team's agreement
            $registrationDetail = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', auth()->id())
                ->first();

            // Check if registration details do not exist or term_accept is not 1
            if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
                return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
            }

            // Proceed with sending the invitation
            TeamUserRegistrationDetail::updateOrCreate(
                ['team_id' => $request->team_id, 'user_id' => $request->user_id],
                ['term_accept' => 1, 'invite_send' => 1, 'invite_by' => auth()->id()]
            );

            // Retrieve the user's details
            $user = ClientDetail::where('user_id', $request->user_id)->first();
            $userName = $user ? $user->fullname : 'User';
            $userEmail = $user ? $user->user->email : null;

            // Retrieve the team details and generate the team link
            $team = Team::findOrFail($request->team_id);
            $teamLink = route('client.teams', ['teamSlug' => $team->team_slug]);

            // Send the invitation email
            if ($userEmail) {
                Mail::to($userEmail)->send(new TeamInvitationMail($userName, $team->name, $teamLink));
            }

            return $this->apiResponse('Invitation sent successfully.', true, [
                'userName' => $userName,
                'userId' => $request->user_id
            ], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('Failed to send invitation.', false, [], 500);
        }
    }


    public function removeInvite(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'user_id' => 'required|exists:users,id', // Household user ID
        ]);

        try {

            // Check if the user has accepted the team's agreement
            $registrationDetail = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', auth()->id())
                ->first();

            // Check if registration details do not exist or term_accept is not 1
            if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
                return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
            }
            // Retrieve the user's name from ClientDetail before deletion
            $user = ClientDetail::where('user_id', $request->user_id)->first();
            $userName = $user ? $user->fullname : 'User';

            TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', $request->user_id)
                ->delete();


            return $this->apiResponse('Invite removed successfully.', true, [
                'userName' => $userName,
                'userId' => $request->user_id
            ], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('Failed to remove invite.', false, [], 500);
        }
    }

    public function acceptContract(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'contract_id' => 'required|exists:team_contracts,contract_id',
        ]);

        try {

            // Check if the user has accepted the team's agreement
            $registrationDetail = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', auth()->id())
                ->first();

            // Check if registration details do not exist or term_accept is not 1
            if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
                return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
            }

            TeamUserRegistrationContact::updateOrCreate(
                [
                    'team_id' => $request->team_id,
                    'contract_id' => $request->contract_id,
                    'user_id' => Auth::id()
                ],
                [
                    'user_ip_address' => $request->ip(),
                    'user_current_location' => $request->user_location // Capture location if available
                ]
            );


            return $this->apiResponse('Contract accepted successfully.', true, [], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('Failed to accept contract.', false, [], 500);
        }
    }
    public function storeAnswers(Request $request, $teamId)
    {

        // Check if the user has accepted the team's agreement
        $registrationDetail = TeamUserRegistrationDetail::where('team_id', $teamId)
            ->where('user_id', auth()->id())
            ->first();

        // Check if registration details do not exist or term_accept is not 1
        if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
            return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
        }
        $validator = Validator::make($request->all(), [
            'answers.*.question_id' => 'required|exists:team_questions,id',
            'answers.*.answer' => 'required'
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();
            $errorMessages = [];

            // Process validation errors
            foreach ($errors->get('answers.*.answer') as $field => $messages) {
                foreach ($messages as $message) { // Iterate over each error message
                    preg_match('/answers\.(\d+)\.answer/', $field, $matches);
                    $index = $matches[1] ?? null;
                    if ($index !== null && isset($request->answers[$index]['question_id'])) {
                        $questionId = $request->answers[$index]['question_id'];
                        $question = Question::find($questionId); // Assuming a `TeamQuestion` model exists
                        $errorMessages[] = $question ? "{$question->question_text} requires an answer." : "An answer is required.";
                    }
                }
            }



            return $this->apiResponse('Validation failed.', false, $errorMessages, 422);
        }



        foreach ($request->answers as $answerData) {
            $answer = is_array($answerData['answer']) ? json_encode($answerData['answer']) : $answerData['answer'];

            TeamUserAnswer::updateOrCreate(
                [
                    'team_id' => $teamId,
                    'user_id' => Auth::id(),
                    'question_id' => $answerData['question_id']
                ],
                [
                    'answer' => $answer
                ]
            );
        }

        return $this->apiResponse('Answers saved successfully.', true, [], 200);
    }


    public function selectSalesItem(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'sale_item_id' => 'nullable|exists:team_sale_items,id', // Optional item
        ]);

        try {
            // Check if the user has accepted the team's agreement
            $registrationDetail = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', auth()->id())
                ->first();

            if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
                return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
            }

            // Find the team registration record
            $teamRegistration = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', Auth::id())
                ->firstOrFail();

            // Get team details to get mandatory items
            $teamDetails = Team::findOrFail($request->team_id);
            $mandatorySaleItemIds = json_decode($teamDetails->mandatory_sale_item_ids, true) ?? [];

            // Prepare the sales_items_id value
            $salesItemsValue = null;

            if (!empty($mandatorySaleItemIds) && $request->sale_item_id) {
                // Both mandatory and optional items exist
                $allItems = array_merge($mandatorySaleItemIds, [$request->sale_item_id]);
                $salesItemsValue = json_encode(array_unique($allItems));
            } elseif (!empty($mandatorySaleItemIds) && !$request->sale_item_id) {
                // Only mandatory items exist
                if (count($mandatorySaleItemIds) === 1) {
                    $salesItemsValue = $mandatorySaleItemIds[0]; // Store as single ID
                } else {
                    $salesItemsValue = json_encode($mandatorySaleItemIds); // Store as JSON array
                }
            } elseif ($request->sale_item_id) {
                // Only optional item selected
                $salesItemsValue = $request->sale_item_id;
            }

            // Update the registration record
            $teamRegistration->update([
                'sales_items_id' => $salesItemsValue
            ]);

            // Prepare response message
            $message = 'Sales selection saved successfully.';
            if (!empty($mandatorySaleItemIds) && $request->sale_item_id) {
                $message = 'Mandatory and optional sales items selected successfully.';
            } elseif (!empty($mandatorySaleItemIds) && !$request->sale_item_id) {
                $message = 'Mandatory sales items confirmed successfully.';
            } elseif ($request->sale_item_id) {
                $message = 'Optional sales item selected successfully.';
            }

            return $this->apiResponse($message, true, [], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('An error occurred: ' . $e->getMessage(), false, [], 500);
        }
    }
    public function selectAddonItems(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'addon_items_ids' => 'nullable|array',
            'addon_items_ids.*' => 'exists:team_addon_items,id',
        ]);

        // Ensure `addon_items_ids` is always set, either with values or as an empty array
        $addonItemIds = $request->has('addon_items_ids') ? $validated['addon_items_ids'] : [];

        try {

            // Check if the user has accepted the team's agreement
            $registrationDetail = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', auth()->id())
                ->first();

            // Check if registration details do not exist or term_accept is not 1
            if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
                return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
            }
            // Find the team registration record for the current user and specified team
            $teamRegistration = TeamUserRegistrationDetail::where('team_id', $validated['team_id'])
                ->where('user_id', Auth::id())
                ->firstOrFail();

            // Update the 'addon_items_ids' field:
            // - Set it to null if `addon_items_ids` is empty
            // - JSON encode `addon_items_ids` if it has values
            $teamRegistration->update([
                'addon_items_ids' => !empty($addonItemIds) ? json_encode($addonItemIds) : null
            ]);

            return $this->apiResponse('Optional items selected successfully.', true, [], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('An error occurred: ' . $e->getMessage(), false, [], 500);
        }
    }

    /**
     * Store or update card details for a user and team.
     */
    public function storeCardDetails(Request $request)
    {
        // Step 1: Validation
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'card_number' => 'required|digits:16',
            'card_holder_name' => 'required|string|max:255',
            'expiry_date' => 'required|date_format:m/y|after:today',
            'cvv' => 'required|digits:3',
            'billing_address' => 'required|string|max:255',
            'billing_city' => 'required|string|max:255',
            'billing_state' => 'required|string|max:255',
            'billing_zip' => 'required|string|max:10',
            'billing_country' => 'required|string|max:255',
        ]);

        try {
            $userId = Auth::id();
            $teamId = $validated['team_id'];

            // Prepare the card details array
            $cardDetails = [
                'card_number' => $validated['card_number'],
                'card_holder_name' => $validated['card_holder_name'],
                'expiry_date' => $validated['expiry_date'],
                'cvv' => $validated['cvv'],
                'billing_address' => $validated['billing_address'],
                'billing_city' => $validated['billing_city'],
                'billing_state' => $validated['billing_state'],
                'billing_zip' => $validated['billing_zip'],
                'billing_country' => $validated['billing_country'],
            ];

            // Update or create card details
            $cardDetail = TeamUserRegistrationCardDetail::updateOrCreate(
                [
                    'user_id' => $userId,
                    'team_id' => $teamId,
                ],
                [
                    'card_details' => $cardDetails,
                ]
            );

            // Mask card number for frontend display
            $maskedCardNumber = '**** **** **** ' . substr($validated['card_number'], -4);

            return response()->json([
                'success' => true,
                'message' => 'Card details saved successfully.',
                'card_holder_name' => $validated['card_holder_name'],
                'card_number' => $maskedCardNumber,
                'expiry_date' => $validated['expiry_date'],
            ]);
        } catch (\Exception $e) {
            \Log::error("Failed to save card details for user {$userId} on team {$teamId}. Error: " . $e->getMessage());
            return response()->json(['success' => false, 'message' => 'An error occurred while saving card details.'], 500);
        }
    }
    public function storeAutoPayment(Request $request)
    {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'auto_payment' => 'required|boolean',
        ]);

        try {

            // Check if the user has accepted the team's agreement
            $registrationDetail = TeamUserRegistrationDetail::where('team_id', $request->team_id)
                ->where('user_id', auth()->id())
                ->first();

            // Check if registration details do not exist or term_accept is not 1
            if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
                return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
            }



            $userId = Auth::id();
            $teamId = $validated['team_id'];
            $ipAddress = $request->ip();
            $autoPaymentAcceptTime = now();



            TeamUserRegistrationCardDetail::where('user_id', $userId)
                ->where('team_id', $teamId)
                ->update([
                    'auto_payment' => $validated['auto_payment'],
                    'ip_address' => $ipAddress,
                    'auto_payment_accept_time' => $autoPaymentAcceptTime,
                ]);

            return $this->apiResponse('Auto-payment settings saved successfully.', true, [], 200);
        } catch (\Exception $e) {
            return $this->apiResponse('Failed to save auto-payment settings.', false, [], 500);
        }
    }

    public function calculateInstallmentOptions($teamId)
    {
        $team = TeamUserRegistrationDetail::where('team_id', $teamId)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        // Get the team details to fetch mandatory items
        $teamDetails = Team::findOrFail($teamId);

        // Get mandatory sales items
        $mandatorySaleItemIds = json_decode($teamDetails->mandatory_sale_item_ids, true) ?? [];
        $mandatorySalesItems = TeamSaleItem::whereIn('id', $mandatorySaleItemIds)
            ->where('status', 'active')
            ->get();

        // Get selected optional sales item
        $selectedSalesItem = null;
        if ($team->sales_items_id) {
            $selectedSalesItem = TeamSaleItem::where('id', $team->sales_items_id)->first();
        }

        // Get selected addon items
        $addonItems = json_decode($team->addon_items_ids, true) ?: [];
        $addonItems = !empty($addonItems)
            ? TeamAddonItem::whereIn('id', $addonItems)->where('status', 'active')->get()
            : collect();

        // Calculate total prices
        $mandatoryItemsPrice = $mandatorySalesItems->sum('price');
        $mandatoryItemsPartialAmount = $mandatorySalesItems->sum('partial_amount_due');

        $selectedSalesItemPrice = $selectedSalesItem ? $selectedSalesItem->price : 0;
        $selectedSalesItemPartialAmount = $selectedSalesItem ? $selectedSalesItem->partial_amount_due : 0;

        $addonItemsPrice = $addonItems->sum('price');
        $addonItemsPartialAmount = $addonItems->sum('partial_amount_due');

        // Calculate upfront amount based on partial amounts due
        $upfrontAmountCredit = $mandatoryItemsPartialAmount + $selectedSalesItemPartialAmount + $addonItemsPartialAmount;

        // Add 3.5% processing fee to upfront amount
        $upfrontAmount = $upfrontAmountCredit + ($upfrontAmountCredit * 0.035);

        // If upfront amount is 0, set it to 1 for processing
        if ($upfrontAmountCredit == 0) {
            $upfrontAmountCredit = 1;
            $upfrontAmount = 1 + (1 * 0.035);
        }

        // Calculate total amount (mandatory + selected + addons)
        $totalPriceBeforeFees = $mandatoryItemsPrice + $selectedSalesItemPrice + $addonItemsPrice;
        $totalAmount = $totalPriceBeforeFees + ($totalPriceBeforeFees * 0.035);

        // Calculate the remaining amount due for EMI calculation
        $remainingAmountDue = $totalAmount - $upfrontAmount;

        // Get payment terms for the team
        $paymentTerms = TeamPaymentSchedule::where('team_id', $teamId)->get();

        // Calculate installments based on remaining amount and payment terms
        $installmentOptions = [];
        foreach ($paymentTerms as $term) {
            $installmentAmount = ($remainingAmountDue * $term->percentage) / 100;
            $installmentAmount = round($installmentAmount, 2); // Round to 2 decimal places

            $installmentOptions[] = [
                'installment_number' => $term->installment_number,
                'amount_due' => $installmentAmount,
                'due_date' => Carbon::parse($term->due_date)->format('Y-m-d'),
            ];
        }

        // Response includes breakdown and installment options
        return response()->json([
            'success' => true,
            'total_amount' => $totalAmount,
            'upfront_payment' => $upfrontAmount,
            'installment_options' => $installmentOptions,
            'breakdown' => [
                'mandatory_items_total' => $mandatoryItemsPrice,
                'selected_item_total' => $selectedSalesItemPrice,
                'addon_items_total' => $addonItemsPrice,
                'subtotal' => $totalPriceBeforeFees,
                'processing_fee' => $totalPriceBeforeFees * 0.035,
                'grand_total' => $totalAmount,
            ]
        ]);
    }

    public function processUpfrontPayment(Request $request)
    {
        $teamId = $request->input('teamId');
        $userId = Auth::id();

        $team = Team::findOrFail($teamId); // Assuming `Team` is the model
        $teamSlug = $team->team_slug; // Get the slug from the team details
        // Check if the user has accepted the team's agreement
        $registrationDetail = TeamUserRegistrationDetail::where('team_id', $team->id)
            ->where('user_id', auth()->id())
            ->first();

        // Check if registration details do not exist or term_accept is not 1
        if (!$registrationDetail || $registrationDetail->term_accept !== 1) {
            return $this->apiResponse('You must accept the team agreement before proceeding to the next step.', false, [], 403);
        }

        // Calculate installment options
        $installmentData = $this->calculateInstallmentOptions($teamId)->getData();




        if (!$installmentData->success) {
            return $this->apiResponse('Failed to calculate installment options.', false, [], 500);
        }

        $upfrontPayment = $installmentData->upfront_payment;



        // Generate a unique transaction reference ID for each payment attempt
        $upfrontTransactionReferenceId = Str::random(16);



        // Prepare payment data for upfront payment
        $paymentData = [
            'transactionReferenceId' => $upfrontTransactionReferenceId,
            'amount' => $upfrontPayment, // Use the upfront payment amount
            'customerName' => Auth::user()->name,
            'customerEmail' => Auth::user()->email,
            'customerMobile' => Auth::user()->phone,



            'cancelUrl' => route('payment.cancel', [
                'teamSlug' => $teamSlug,
                'transactionReferenceId' => $upfrontTransactionReferenceId
            ]),
            'failureUrl' => route('payment.failure', [

                'transactionReferenceId' => $upfrontTransactionReferenceId
            ]),
            'returnUrl' => route('payment.success'),


        ];


        // Process payment using IPOSpaysService
        $iposService = new IPOSpaysService();
        $response = $iposService->processInitialPayment($paymentData);


        if (isset($response['error']) && $response['error']) {
            // return response()->json([
            //     'error' => true,
            //     'message' => $response['message'],
            // ], $response['status']);

            return $this->apiResponse($response['message'], false, [], $response['status']);
        } else {
            // Extract response data
            $transactionId = $response['transactionId'] ?? null;
            $rrn = $response['RRN'] ?? null;
            $cardToken = $response['responseCardToken'] ?? null;
            $paymentUrl = $response['information'] ?? null;

            if ($paymentUrl) {
                // Save or update the upfront payment details in the schedule
                $this->saveOrUpdatePaymentDetails($userId, $teamId, $upfrontTransactionReferenceId, $transactionId, $rrn, $upfrontPayment, 'unpaid');

                // Save upcoming installment options only if they don’t already exist
                foreach ($installmentData->installment_options as $installment) {
                    $installmentTransactionReferenceId = Str::random(16); // Unique transaction reference ID for each installment
                    $this->saveOrUpdatePaymentDetails(
                        $userId,
                        $teamId,
                        $installmentTransactionReferenceId,
                        null, // No transactionId initially
                        null, // No RRN for unpaid installments
                        $installment->amount_due,
                        'unpaid',
                        $installment->installment_number,
                        $installment->due_date
                    );
                }



                return $this->apiResponse('Payment URL generated successfully.', true, [
                    'paymentUrl' => $paymentUrl,
                    'transactionReferenceId' => $upfrontTransactionReferenceId,
                ], 200);
            } else {
                return $this->apiResponse('Payment URL not found in the response.', false, [], 500);
            }
        }
    }
    /**
     * Save or update payment details in team_user_payments_schedule.
     */
    private function saveOrUpdatePaymentDetails($userId, $teamId, $transactionReferenceId, $transactionId, $rrn, $amount, $status, $installment = null, $schedule = null)
    {
        // Check if a record already exists with the same user_id, team_id, and installment
        $existingRecord = TeamUserPaymentsSchedule::where('user_id', $userId)
            ->where('team_id', $teamId)
            ->where('installment', $installment)
            ->first();

        if ($existingRecord) {
            // Update existing record with new transactionReferenceId and payment details
            $existingRecord->update([
                'transactionReferenceId' => $transactionReferenceId,
                'transactionId' => $transactionId,
                'RRN' => $rrn,
                'amount' => $amount,
                'status' => $status,
                'next_payment_schedule' => $schedule,
            ]);
        } else {
            // If no record exists, create a new one
            TeamUserPaymentsSchedule::create([
                'user_id' => $userId,
                'team_id' => $teamId,
                'transactionReferenceId' => $transactionReferenceId,
                'transactionId' => $transactionId,
                'RRN' => $rrn,
                'amount' => $amount,
                'status' => $status,
                'installment' => $installment,
                'next_payment_schedule' => $schedule,
            ]);
        }
    }

    /**
     * Store card details securely in the team_user_registration_carddetails table.
     */
    private function updateCardToken($userId, $teamId, $cardToken)
    {
        TeamUserRegistrationCardDetail::updateOrCreate(
            ['user_id' => $userId, 'team_id' => $teamId],
            ['card_token' => $cardToken]
        );
    }
    public function success(Request $request)
    {
        // Update the payment record with transactionId and set status to 'paid'
        $data = TeamUserPaymentsSchedule::where('transactionReferenceId', $request->transactionReferenceId)
            ->first();

        if ($data) {
            $data->update([
                'status' => 'paid',
                'transactionId' => $request->transactionId,  // Set transaction ID upon success
                'RRN' => $request->RRN,  // Set RRN upon success
                'last_  ment_date' => now(),  // Set last payment date upon success
            ]);
        }

        if ($request->responseCardToken) {
            $this->updateCardToken(Auth::id(), $data->team_id, $request->responseCardToken);
        }

        if ($data && $data->team) {
            // Fetch all payment schedules
            $paymentSchedules = TeamUserPaymentsSchedule::where('team_id', $data->team_id)
                ->where('user_id', Auth::id())
                ->orderBy('installment', 'asc')
                ->get();
            TeamPaymentCompleted::dispatch($data->team, Auth::user(), $data);
            ClientTeamPaymentCompleted::dispatch($data->team, Auth::user(), $data);


            // Send email with payment receipt and schedule

            Mail::to(Auth::user()->email)->send(new \App\Mail\PaymentReceipt($data, $paymentSchedules));

            return redirect()->route('client.teams', ['teamSlug' => $data->team->team_slug])
                ->with('success', 'Payment successful. A receipt has been sent to your email.');
        }

        return redirect()->route('client.teams')->with('error', 'Payment record not found.');
    }



    public function failure(Request $request)
    {
        // print_r($request->all());
    }
    public function cancel($teamSlug)
    {
        // Logic to handle cancellation
        return redirect()->route('client.teams', ['teamSlug' => $teamSlug])
            ->with('error', 'Payment has been canceled.');
    }
    public function getNextPayment(Request $request)
    {
        $userId = auth()->id();
        $teamId = $request->team_id;

        // Fetch all installments for the user and team, ordered by installment number
        $installments = TeamUserPaymentsSchedule::where('user_id', $userId)
            ->where('team_id', $teamId)
            ->orderBy('installment', 'asc')
            ->get();

        // Find the next pending payment
        $nextPendingPayment = $installments->firstWhere('status', 'unpaid');

        if ($nextPendingPayment) {
            return response()->json([
                'success' => true,
                'nextPayment' => $nextPendingPayment
            ]);
        }

        // If no pending payment is found
        return response()->json([
            'success' => false,
            'message' => 'No pending payments found.'
        ]);
    }

   protected $verticalInsureService;

public function __construct(VerticalInsureService $verticalInsureService)
{
    $this->verticalInsureService = $verticalInsureService;
}

public function selectInsurance(Request $request)
{
    try {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'insurance_opted' => 'required|in:true,false,1,0',
            'insurance_type' => 'nullable|string|max:255',
            'insurance_status' => 'nullable|string|in:pending,selected,active,cancelled,expired,skipped',
            'insurance_quote_data' => 'nullable|array',
        ]);

        $userId = Auth::id();
        $teamId = $validated['team_id'];
        $insuranceOpted = in_array($validated['insurance_opted'], [true, 'true', 1, '1']);

        // Check if user already has pending or active insurance for this team
        $existingInsurance = TeamUserInsuranceDetail::where('team_id', $teamId)
            ->where('user_id', $userId)
            ->whereIn('insurance_status', ['pending', 'active'])
            ->first();

        if ($existingInsurance && $insuranceOpted) {
            $statusMessage = $existingInsurance->insurance_status === 'active'
                ? 'Insurance already purchased for this team.'
                : 'Insurance purchase already in progress. Please complete your pending payment or check status.';

            return response()->json([
                'status' => false,
                'message' => $statusMessage,
                'data' => [
                    'existing_status' => $existingInsurance->insurance_status,
                    'policy_number' => $existingInsurance->insurance_policy_id,
                    'amount' => $existingInsurance->insurance_amount,
                ]
            ], 409); // 409 Conflict
        }

        // Process with service only if no pending/active insurance exists
        $insuranceDetail = $this->verticalInsureService->processSelection(
            $userId,
            $teamId,
            [
                'insurance_opted' => $insuranceOpted,
                'insurance_type' => $validated['insurance_type'] ?? 'gap-medical',
                'insurance_status' => $validated['insurance_status'] ?? ($insuranceOpted ? 'pending' : 'skipped'),
                'insurance_quote_data' => $validated['insurance_quote_data'] ?? null,
            ]
        );

        return response()->json([
            'status' => true,
            'message' => $insuranceOpted ? 'Insurance selection saved. Complete payment and check status manually.' : 'Insurance opt-out confirmed.',
            'data' => [
                'insurance_id' => $insuranceDetail->id,
                'insurance_opted' => $insuranceDetail->insurance_opted,
                'insurance_status' => $insuranceDetail->insurance_status,
                'insurance_amount' => $insuranceDetail->insurance_amount,
            ]
        ]);
    } catch (\Exception $e) {
        return response()->json([
            'status' => false,
            'message' => 'An error occurred while processing insurance selection: ' . $e->getMessage()
        ], 500);
    }
}

public function checkInsuranceStatus(Request $request)
{
    try {
        $teamId = $request->input('team_id');
        $quoteId = $request->input('quote_id');
        $userId = Auth::id();

        // Only check our database - no automatic API calls
        $status = $this->verticalInsureService->checkStatus($teamId, $userId, $quoteId);

        return response()->json($status);
    } catch (\Exception $e) {
        return response()->json([
            'status' => false,
            'message' => 'Failed to check insurance status'
        ], 500);
    }
}

public function updateInsuranceStatus(Request $request)
{
    try {
        $validated = $request->validate([
            'team_id' => 'required|exists:teams,id',
            'policy_number' => 'required|string',
            'status' => 'required|string',
            'amount' => 'nullable|numeric'
        ]);

        $userId = Auth::id();

        // Manual update for admin use
        $insuranceDetail = TeamUserInsuranceDetail::where('team_id', $validated['team_id'])
            ->where('user_id', $userId)
            ->first();

        if ($insuranceDetail) {
            $updateData = [
                'insurance_policy_id' => $validated['policy_number'],
                'insurance_status' => $validated['status'],
                'purchased_at' => now(),
            ];

            if (isset($validated['amount'])) {
                $updateData['insurance_amount'] = $validated['amount'];
            }

            $insuranceDetail->update($updateData);

            return response()->json([
                'status' => true,
                'message' => 'Insurance status updated successfully',
                'data' => $insuranceDetail
            ]);
        }

        return response()->json([
            'status' => false,
            'message' => 'Insurance record not found'
        ]);
    } catch (\Exception $e) {
        return response()->json([
            'status' => false,
            'message' => 'Failed to update insurance status'
        ], 500);
    }
}

public function handleInsuranceReturn(Request $request)
{
    try {
        // Optional return handler if Vertical Insure supports return URLs
        $policyNumber = $request->input('policy_number');
        $status = $request->input('status', 'active');
        $teamId = $request->input('team_id');
        $amount = $request->input('amount', 0);
        $userId = Auth::id();

        if (!$teamId) {
            // Try to find pending insurance
            $pendingInsurance = TeamUserInsuranceDetail::where('user_id', $userId)
                ->where('insurance_status', 'pending')
                ->latest()
                ->first();

            if ($pendingInsurance) {
                $teamId = $pendingInsurance->team_id;
            }
        }

        if ($teamId && $policyNumber) {
            // Update insurance record
            TeamUserInsuranceDetail::where('team_id', $teamId)
                ->where('user_id', $userId)
                ->update([
                    'insurance_policy_id' => $policyNumber,
                    'insurance_status' => $status,
                    'insurance_amount' => $amount > 0 ? $amount : null,
                    'purchased_at' => now(),
                ]);
        }

        $team = Team::find($teamId);
        if ($team) {
            return redirect()
                ->route('client.teams', ['teamSlug' => $team->team_slug])
                ->with('insurance_success', [
                    'policy_number' => $policyNumber,
                    'amount' => $amount,
                    'message' => 'Insurance purchased successfully!'
                ]);
        }

        return redirect()->route('client.teams')->with('success', 'Insurance purchase completed!');
    } catch (\Exception $e) {
        return redirect()->route('client.teams')->with('error', 'Insurance return handling failed.');
    }
}

}
 <?php
// app/Services/VerticalInsureService.php

namespace App\Services;

use App\Models\TeamUserInsuranceDetail;
use Illuminate\Support\Facades\Log;
use Exception;

class VerticalInsureService
{
    protected $clientId;
    protected $baseUrl;
    protected $apiKey;

    public function __construct()
    {
        $this->clientId = config('services.vertical_insure.client_id');
        $this->baseUrl = config('services.vertical_insure.base_url', 'https://api.verticalinsure.com');
        $this->apiKey = config('services.vertical_insure.api_key');
    }

    /**
     * Initialize the Vertical Insure widget
     */
    public function initializeWidgetConfig($user, $team = null)
    {
        $userData = [
            'email_address' => $user->email,
            'first_name' => $user->name,
            'last_name' => '',
            'state' => $team->state ?? 'CA',
            'postal_code' => $team->postal_code ?? '90210'
        ];

        $coverageStartDate = $team->start_date ?? date('Y-m-d');
        $coverageEndDate = $team->end_date ?? date('Y-m-d', strtotime('+3 months'));

        return [
            'client_id' => $this->clientId,
            'payments' => ['enabled' => false],
            'product_config' => [
                "gap-medical" => [[
                    "customer" => $userData,
                    "policy_attributes" => [
                        "coverage_end_date" => $coverageEndDate,
                        "coverage_start_date" => $coverageStartDate,
                        "coverage_type" => "SOCCER",
                        "covered_person" => [
                            "birth_date" => $user->date_of_birth ?? '1990-01-01',
                            "state" => $userData['state'],
                            "first_name" => $userData['first_name'],
                            "last_name" => $userData['last_name'] ?: "Player",
                            "street" => "NA"
                        ]
                    ]
                ]]
            ],
            'theme' => [
                'colors' => ['primary' => "#A72800", 'background' => "#ffffff"]
            ]
        ];
    }

    /**
     * Process insurance selection with cleaned up amount handling
     */
    public function processSelection($userId, $teamId, $data)
    {
        try {
            // Extract insurance amount from quote data if available
            $insuranceAmount = 0;
            if (!empty($data['insurance_quote_data']) && isset($data['insurance_quote_data']['premium_amount'])) {
                $insuranceAmount = $data['insurance_quote_data']['premium_amount'] / 100; // Convert cents to dollars
            }

            $insuranceData = [
                'team_id' => $teamId,
                'user_id' => $userId,
                'insurance_opted' => $data['insurance_opted'] ?? false,
                'insurance_type' => $data['insurance_type'] ?? 'gap-medical',
                'insurance_amount' => $insuranceAmount, // Get from quote data
                'insurance_status' => $data['insurance_status'] ?? ($data['insurance_opted'] ? 'selected' : 'skipped'),
                'user_ip_address' => request()->ip(),
            ];

            if (!empty($data['insurance_quote_data'])) {
                $insuranceData['insurance_quote_data'] = json_encode($data['insurance_quote_data']);

                // Store quote ID for tracking
                if (isset($data['insurance_quote_data']['quote_id'])) {
                    $insuranceData['quote_reference'] = $data['insurance_quote_data']['quote_id'];
                }
            }

            return TeamUserInsuranceDetail::updateOrCreate(
                ['team_id' => $teamId, 'user_id' => $userId],
                $insuranceData
            );
        } catch (Exception $e) {
            Log::error("VerticalInsureService - processSelection error: " . $e->getMessage());
            throw $e;
        }
    }

    public function checkStatus($teamId, $userId, $quoteId = null)
    {
        $insuranceDetail = TeamUserInsuranceDetail::where('team_id', $teamId)
            ->where('user_id', $userId)
            ->first();

        if (!$insuranceDetail) {
            return [
                'status' => false,
                'data' => [
                    'insurance_purchased' => false,
                    'insurance_status' => null,
                    'policy_number' => null,
                    'insurance_amount' => 0
                ]
            ];
        }

        $isPurchased = false;

        // Check by status
        if (in_array($insuranceDetail->insurance_status, ['active', 'completed'])) {
            $isPurchased = true;
        }

        // Check if we have a real policy number
        if ($insuranceDetail->insurance_policy_id &&
            (strpos($insuranceDetail->insurance_policy_id, 'CS-VGM-AC-') === 0 ||
             strpos($insuranceDetail->insurance_policy_id, 'POL_') === 0)) {
            $isPurchased = true;
        }

        // Check if purchased_at is set
        if ($insuranceDetail->purchased_at) {
            $isPurchased = true;
        }

        // Override if explicitly opted out
        if (!$insuranceDetail->insurance_opted) {
            $isPurchased = false;
        }

        return [
            'status' => true,
            'data' => [
                'insurance_purchased' => $isPurchased,
                'insurance_status' => $insuranceDetail->insurance_status,
                'policy_number' => $insuranceDetail->insurance_policy_id,
                'insurance_amount' => $insuranceDetail->insurance_amount,
                'purchased_at' => $insuranceDetail->purchased_at,
                'insurance_opted' => $insuranceDetail->insurance_opted
            ]
        ];
    }

    public function updateStatus($teamId, $userId, $policyNumber, $status = 'active')
    {
        try {
            $insuranceDetail = TeamUserInsuranceDetail::where('team_id', $teamId)
                ->where('user_id', $userId)
                ->first();

            if ($insuranceDetail) {
                $insuranceDetail->update([
                    'insurance_policy_id' => $policyNumber,
                    'insurance_status' => $status,
                    'purchased_at' => now(),
                    'vertical_insure_response' => json_encode([
                        'manual_update' => true,
                        'policy_number' => $policyNumber,
                        'updated_at' => now()->toISOString()
                    ])
                ]);

                return [
                    'status' => true,
                    'message' => 'Insurance status updated successfully',
                    'data' => $insuranceDetail
                ];
            }

            return [
                'status' => false,
                'message' => 'Insurance record not found'
            ];
        } catch (Exception $e) {
            Log::error("VerticalInsureService - updateStatus error: " . $e->getMessage());
            throw $e;
        }
    }

    public function processPaymentCompletion($teamId, $userId, $paymentData)
    {
        try {
            $insuranceDetail = TeamUserInsuranceDetail::where('team_id', $teamId)
                ->where('user_id', $userId)
                ->firstOrFail();

            // Extract amount from payment data or keep existing amount
            $insuranceAmount = $paymentData['amount'] ?? $insuranceDetail->insurance_amount;

            $insuranceDetail->update([
                'insurance_policy_id' => $paymentData['policy_number'],
                'insurance_status' => 'active',
                'insurance_amount' => $insuranceAmount,
                'vertical_insure_response' => json_encode($paymentData),
                'purchased_at' => now(),
                'payment_reference' => $paymentData['payment_id'] ?? null,
            ]);

            return $insuranceDetail;
        } catch (Exception $e) {
            Log::error("VerticalInsureService - processPaymentCompletion error: " . $e->getMessage());
            throw $e;
        }
    }
}
review this vertical insure code