<?php

namespace App\Http\Controllers;

use App\Models\JointAccount;
use App\Models\JointAccountMember;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class JointAccountController extends Controller
{
    public function index(): JsonResponse
    {
        try {
            $user = Auth::user();
            
            // Get active joint accounts where user is a member
            $activeJointAccounts = JointAccount::whereHas('members', function($query) use ($user) {
                $query->where('user_id', $user->id)->where('status', 'active');
            })
            ->with(['members.user', 'creator'])
            ->withCount('activeMembers')
            ->latest()
            ->get();

            // Get pending invitations for the user
            $pendingInvitations = JointAccount::whereHas('members', function($query) use ($user) {
                $query->where('user_id', $user->id)->where('status', 'pending');
            })
            ->with(['members.user', 'creator'])
            ->latest()
            ->get();

            return response()->json([
                'status' => 'success',
                'joint_accounts' => $activeJointAccounts,
                'pending_invitations' => $pendingInvitations,
                'debug' => [
                    'user_id' => $user->id,
                    'user_email' => $user->email,
                    'active_accounts_count' => $activeJointAccounts->count(),
                    'pending_invitations_count' => $pendingInvitations->count()
                ]
            ]);
        } catch (\Exception $e) {
            \Log::error('Joint Account Index Error: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch joint accounts',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function store(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'account_name' => 'required|string|max:255',
                'description' => 'nullable|string|max:1000',
                'minimum_approval_amount' => 'required|numeric|min:0',
                'approval_type' => 'required|in:any_member,majority,all_members,specific_amount',
                'members' => 'required|array|min:1',
                'members.*.email' => 'required|email|exists:users,email',
                'members.*.role' => 'required|in:admin,member,viewer'
            ]);

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

            DB::beginTransaction();

            // Create joint account with pending status
            $jointAccount = JointAccount::create([
                'account_name' => $request->account_name,
                'description' => $request->description,
                'minimum_approval_amount' => $request->minimum_approval_amount,
                'approval_type' => $request->approval_type,
                'status' => 'pending',
                'created_by' => Auth::id()
            ]);

            // Add creator as owner
            JointAccountMember::create([
                'joint_account_id' => $jointAccount->id,
                'user_id' => Auth::id(),
                'role' => 'owner',
                'status' => 'active',
                'joined_at' => now()
            ]);

            // Add other members
            foreach ($request->members as $memberData) {
                $user = User::where('email', $memberData['email'])->first();
                
                JointAccountMember::create([
                    'joint_account_id' => $jointAccount->id,
                    'user_id' => $user->id,
                    'role' => $memberData['role'],
                    'status' => 'pending',
                    'invited_by' => Auth::id()
                ]);
            }

            DB::commit();

            // Load relationships for response
            $jointAccount->load(['members.user', 'creator']);

            return response()->json([
                'status' => 'success',
                'message' => 'Joint account created successfully',
                'joint_account' => $jointAccount
            ], 201);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to create joint account',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function show($id): JsonResponse
    {
        try {
            $user = Auth::user();
            
            $jointAccount = JointAccount::with([
                'members.user',
                'creator',
                'transactions' => function($query) {
                    $query->latest()->limit(10);
                },
                'transactions.initiator',
                'transactions.approvals.approver'
            ])->find($id);

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

            // Check if user is a member
            if (!$jointAccount->isMember($user)) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Access denied'
                ], 403);
            }

            return response()->json([
                'status' => 'success',
                'joint_account' => $jointAccount
            ]);

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

    public function update(Request $request, $id): JsonResponse
    {
        try {
            $user = Auth::user();
            $jointAccount = JointAccount::find($id);

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

            // Check if user can modify account (owner or admin)
            $userRole = $jointAccount->getMemberRole($user);
            if (!in_array($userRole, ['owner', 'admin'])) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Access denied'
                ], 403);
            }

            $validator = Validator::make($request->all(), [
                'account_name' => 'sometimes|required|string|max:255',
                'description' => 'nullable|string|max:1000',
                'minimum_approval_amount' => 'sometimes|required|numeric|min:0',
                'approval_type' => 'sometimes|required|in:any_member,majority,all_members,specific_amount',
                'status' => 'sometimes|required|in:active,suspended,closed'
            ]);

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

            $jointAccount->update($request->only([
                'account_name',
                'description', 
                'minimum_approval_amount',
                'approval_type',
                'status'
            ]));

            return response()->json([
                'status' => 'success',
                'message' => 'Joint account updated successfully',
                'joint_account' => $jointAccount->fresh(['members.user', 'creator'])
            ]);

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

    public function inviteMember(Request $request, $id): JsonResponse
    {
        try {
            $user = Auth::user();
            $jointAccount = JointAccount::find($id);

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

            $userRole = $jointAccount->getMemberRole($user);
            if (!in_array($userRole, ['owner', 'admin'])) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Access denied'
                ], 403);
            }

            $validator = Validator::make($request->all(), [
                'email' => 'required|email|exists:users,email',
                'role' => 'required|in:admin,member,viewer'
            ]);

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

            $invitedUser = User::where('email', $request->email)->first();

            // Check if user is already a member
            if ($jointAccount->isMember($invitedUser)) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'User is already a member of this account'
                ], 409);
            }

            $member = JointAccountMember::create([
                'joint_account_id' => $jointAccount->id,
                'user_id' => $invitedUser->id,
                'role' => $request->role,
                'status' => 'pending',
                'invited_by' => $user->id
            ]);

            $member->load('user');

            return response()->json([
                'status' => 'success',
                'message' => 'Member invited successfully',
                'member' => $member
            ]);

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

    public function acceptInvitation($id): JsonResponse
    {
        try {
            $user = Auth::user();
            
            $member = JointAccountMember::where('joint_account_id', $id)
                ->where('user_id', $user->id)
                ->where('status', 'pending')
                ->first();

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

            // Update member status to active
            $member->update([
                'status' => 'active',
                'joined_at' => now()
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'Invitation accepted successfully'
            ]);

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

    public function rejectInvitation($id): JsonResponse
    {
        try {
            $user = Auth::user();
            
            $member = JointAccountMember::where('joint_account_id', $id)
                ->where('user_id', $user->id)
                ->where('status', 'pending')
                ->first();

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

            // Update member status to removed instead of deleting
            $member->update([
                'status' => 'removed'
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'Invitation rejected successfully'
            ]);

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