<?php

namespace App\Http\Controllers\Agency;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Agency\AgencyStaff;
use Spatie\Permission\Models\Role;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use App\Models\Agency\AgencyStaffInvitation;
use Illuminate\Support\Str;

class StaffController extends Controller
{
    public function index()
    {
        $agencyId = auth()->user()->currentAgencyId();
        
        $staffMembers = AgencyStaff::with(['user' => function($query) {
            $query->withTrashed();
        }])
        ->where('agency_id', $agencyId)
        ->get();

        $invitations = AgencyStaffInvitation::with('role')
            ->where('agency_id', $agencyId)
            ->where('status', 'pending')
            ->get();

        return view('agency.staff-management.staff.index', compact('staffMembers', 'invitations'));
    }

    public function create()
    {
        $agencyId = auth()->user()->currentAgencyId();
        $roles = Role::where(function($query) use ($agencyId) {
            $query->where('agency_id', $agencyId)
                  ->orWhere(function($q) {
                      $q->whereNull('agency_id')
                        ->whereNotIn('name', ['super-admin', 'system-admin']);
                  });
        })->get();

        return view('agency.staff-management.staff.create', compact('roles'));
    }

    public function store(Request $request)
    {
        $agencyId = auth()->user()->currentAgencyId();

        // Check the action type: 'create_staff' handles both no-user and new-user, 'invite' handles existing user
        $action = $request->input('action_type', 'create_staff');

        if ($action === 'invite') {
            $request->validate([
                'invite_email' => 'required|email|max:255',
                'invite_role_id' => 'required|exists:roles,id',
                'invite_position' => 'nullable|string|max:255',
            ]);

            $targetUser = User::where('email', $request->invite_email)->first();
            if (!$targetUser) {
                return back()->withErrors(['invite_email' => 'Bu e-posta adresine sahip bir kullanıcı bulunamadı.'])->withInput();
            }

            // Check if already in agency
            $existsInAgency = AgencyStaff::where('user_id', $targetUser->id)->where('agency_id', $agencyId)->exists();
            if ($existsInAgency) {
                return back()->withErrors(['invite_email' => 'Bu kullanıcı zaten acentenizde kayıtlı.'])->withInput();
            }

            // Check if already invited
            $existingInvite = AgencyStaffInvitation::where('agency_id', $agencyId)
                                ->where('email', $request->invite_email)
                                ->where('status', 'pending')
                                ->exists();
            if ($existingInvite) {
                return back()->with('error', 'Bu kullanıcıya zaten beklemede olan bir davetiniz var.')->withInput();
            }

            AgencyStaffInvitation::create([
                'agency_id' => $agencyId,
                'email' => $request->invite_email,
                'role_id' => $request->invite_role_id,
                'position' => $request->invite_position,
                'token' => Str::random(60),
                'status' => 'pending'
            ]);

            // Here you would typically notify the user via email / in-app notification
            // TODO: Event / Notification to target user

            return redirect()->route('agency.staff-management.staff.index')
                ->with('success', 'Kullanıcıya başarılı bir şekilde davet gönderildi.');
        }

        // Action is 'create_staff'
        $request->validate([
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:20',
            'position' => 'nullable|string|max:255',
            'hired_at' => 'nullable|date',
            'is_active' => 'boolean'
        ]);

        DB::beginTransaction();
        try {
            // Check if we also want to create a login user
            $createLogin = $request->boolean('create_login_user');
            $user = null;

            if ($createLogin) {
                $request->validate([
                    'email' => 'required|email|max:255|unique:users,email',
                    'password' => 'required|string|min:6|confirmed',
                    'role_id' => 'required|exists:roles,id',
                ]);

                // Create new user
                $user = User::create([
                    'first_name' => $request->first_name,
                    'last_name' => $request->last_name,
                    'email' => $request->email,
                    'password' => Hash::make($request->password),
                    'phone' => $request->phone,
                    'is_active' => $request->is_active ?? true,
                ]);

                // Assign Role (using team context)
                setPermissionsTeamId($agencyId);
                $role = Role::find($request->role_id);
                $user->assignRole($role->name);
            }

            // Create AgencyStaff record
            AgencyStaff::create([
                'agency_id' => $agencyId,
                'user_id' => $user ? $user->id : null,
                'first_name' => $request->first_name,
                'last_name' => $request->last_name,
                'email' => $request->email,
                'phone' => $request->phone,
                'position' => $request->position,
                'hired_at' => $request->hired_at,
                'is_active' => $request->is_active ?? true,
                'can_login' => $createLogin,
            ]);

            DB::commit();
            return redirect()->route('agency.staff-management.staff.index')
                ->with('success', 'Personel başarıyla ' . ($createLogin ? 've sistem girişi ile ' : '') . 'oluşturuldu.');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Personel oluşturulurken bir hata oluştu: ' . $e->getMessage())->withInput();
        }
    }

    public function edit(AgencyStaff $staff)
    {
        $agencyId = auth()->user()->currentAgencyId();
        
        if ($staff->agency_id !== $agencyId) {
            abort(403);
        }

        $roles = Role::where(function($query) use ($agencyId) {
            $query->where('agency_id', $agencyId)
                  ->orWhere(function($q) {
                      $q->whereNull('agency_id')
                        ->whereNotIn('name', ['super-admin', 'system-admin']);
                  });
        })->get();
        
        $currentRole = null;
        if ($staff->user_id) {
            setPermissionsTeamId($agencyId);
            $currentRole = $staff->user->roles->first();
        }

        return view('agency.staff-management.staff.edit', compact('staff', 'roles', 'currentRole'));
    }

    public function update(Request $request, AgencyStaff $staff)
    {
        $agencyId = auth()->user()->currentAgencyId();
        
        if ($staff->agency_id !== $agencyId) {
            abort(403);
        }

        $request->validate([
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:20',
            'position' => 'nullable|string|max:255',
            'hired_at' => 'nullable|date',
            'is_active' => 'boolean'
        ]);

        DB::beginTransaction();
        try {
            $isCreatingUserNow = false;
            $user = $staff->user;

            // If user exists, we validate their email specifically
            if ($user || $request->boolean('create_login_user')) {
                $emailValidation = 'required|email|max:255|unique:users,email' . ($user ? ',' . $user->id : '');
                $request->validate([
                    'email' => $emailValidation,
                ]);
            }

            if (!$user && $request->boolean('create_login_user')) {
                $isCreatingUserNow = true;
                $request->validate([
                    'password' => 'required|string|min:6|confirmed',
                    'role_id' => 'required|exists:roles,id',
                ]);

                // Create new user
                $user = User::create([
                    'first_name' => $request->first_name,
                    'last_name' => $request->last_name,
                    'email' => $request->email,
                    'password' => Hash::make($request->password),
                    'phone' => $request->phone,
                    'is_active' => $request->is_active ?? true,
                ]);

                $staff->user_id = $user->id;
                $staff->can_login = true;
                
                // Assign Role
                setPermissionsTeamId($agencyId);
                $role = Role::find($request->role_id);
                $user->assignRole($role->name);

            } elseif ($user) {
                // Determine validation requirements for existing user password
                $request->validate([
                    'password' => 'nullable|string|min:6|confirmed',
                    'role_id' => 'required|exists:roles,id',
                ]);

                $userData = [
                    'first_name' => $request->first_name,
                    'last_name' => $request->last_name,
                    'email' => $request->email,
                    'phone' => $request->phone,
                    'is_active' => $request->is_active ?? true,
                ];

                if ($request->filled('password')) {
                    $userData['password'] = Hash::make($request->password);
                }

                $user->update($userData);

                // Update Role
                setPermissionsTeamId($agencyId);
                $role = Role::find($request->role_id);
                $user->syncRoles([$role->name]);
            }

            // Update AgencyStaff
            $staff->update([
                'first_name' => $request->first_name,
                'last_name' => $request->last_name,
                'email' => $request->email,
                'phone' => $request->phone,
                'position' => $request->position,
                'hired_at' => $request->hired_at,
                'is_active' => $request->is_active ?? true,
            ]);

            DB::commit();
            return redirect()->route('agency.staff-management.staff.index')
                ->with('success', 'Personel bilgileri güncellendi.');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Güncelleme sırasında bir hata oluştu: ' . $e->getMessage())->withInput();
        }
    }

    public function destroy(AgencyStaff $staff)
    {
        $agencyId = auth()->user()->currentAgencyId();
        
        if ($staff->agency_id !== $agencyId) {
            abort(403);
        }

        if ($staff->is_agency_owner) {
            return back()->with('error', 'Acente sahibini silemezsiniz.');
        }

        DB::beginTransaction();
        try {
            $userId = $staff->user_id;

            // Simply remove from this agency
            $staff->delete();
            
            // Should we delete the user? 
            if ($userId) {
                // In a multi-tenant system, we only delete if they belong to NO other agencies.
                $otherAgenciesCount = AgencyStaff::where('user_id', $userId)->count();
                if ($otherAgenciesCount === 0) {
                    User::find($userId)->delete();
                }
            }

            DB::commit();
            return redirect()->route('agency.staff-management.staff.index')
                ->with('success', 'Personel kaydı silindi.');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Silme işlemi sırasında bir hata oluştu.');
        }
    }

    public function cancelInvitation($id)
    {
        $agencyId = auth()->user()->currentAgencyId();
        
        $invitation = AgencyStaffInvitation::where('agency_id', $agencyId)
            ->where('id', $id)
            ->firstOrFail();

        $invitation->delete();

        return redirect()->route('agency.staff-management.staff.index')
            ->with('success', 'Davet başarıyla iptal edildi.');
    }
}
