<?php

namespace App\Livewire;

use App\Models\User;
use App\Models\Role;
use App\Models\Country;
use App\Models\State;
use App\Models\City;
use App\Services\StaffService;
use App\Traits\HasNotifications;
use Illuminate\Support\Facades\Hash;
use Livewire\Component;
use Livewire\WithFileUploads;

class StaffForm extends Component
{
    use HasNotifications, WithFileUploads;

    public $staffId = null;
    public $currentTab = 'basic';
    public $firstname = '';
    public $middlename = '';
    public $surname = '';
    public $email = '';
    public $phone = '';
    public $password = '';
    public $gender = '';
    public $marital_status = '';
    public $dob = '';
    public $address = '';
    public $country_id = '';
    public $state_id = '';
    public $city_id = '';
    public $nok_name = '';
    public $nok_phone = '';
    public $nok_relationship = '';
    public $nok_address = '';
    public $role_id = '';
    public $active = true;
    public $new_password = '';
    public $confirm_password = '';
    public $countries = [];
    public $states = [];
    public $cities = [];
    public $countriesLoaded = false;
    public $statesLoaded = false;
    public $citiesLoaded = false;
    public $loadingCountries = false;
    public $loadingStates = false;
    public $loadingCities = false;
    public $profile_photo;

    protected $rules = [
        'firstname' => 'required|string|max:255',
        'middlename' => 'nullable|string|max:255',
        'surname' => 'required|string|max:255',
        'email' => 'required|email|unique:users,email',
        'phone' => 'nullable|string|max:20',
        'password' => 'required|min:6',
        'gender' => 'required|in:male,female',
        'marital_status' => 'required|in:single,married,divorced,widowed,other',
        'dob' => 'required|date',
        'address' => 'nullable|string',
        'country_id' => 'nullable|integer',
        'state_id' => 'nullable|integer',
        'city_id' => 'nullable|integer',
        'nok_name' => 'nullable|string|max:255',
        'nok_phone' => 'required|string|max:20',
        'nok_relationship' => 'nullable|string|max:255',
        'nok_address' => 'nullable|string',
        'role_id' => 'required|exists:roles,id',
        'profile_photo' => 'nullable|image|max:500',
    ];

    public function mount($staffId = null)
    {
        if ($staffId) {
            $this->staffId = $staffId;
            $staff = User::with('roles')->findOrFail($staffId);
            $this->fill($staff->toArray());
            $this->role_id = $staff->roles->first()?->id ?? '';
            $this->active = $staff->active ?? true;
            $this->password = '';
            
            if ($this->country_id) {
                $this->loadCountries();
                $this->loadStates();
            }
            if ($this->state_id) {
                $this->loadCities();
            }
        }
    }

    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
        
        if ($propertyName === 'country_id') {
            $this->loadStates();
        }
        
        if ($propertyName === 'state_id') {
            $this->loadCities();
        }
    }
    
    public function loadCountries()
    {
        if (!$this->countriesLoaded) {
            $this->loadingCountries = true;
            $this->countries = Country::orderBy('name')->get();
            $this->countriesLoaded = true;
            $this->loadingCountries = false;
        }
    }
    
    public function loadStates()
    {
        if ($this->country_id) {
            $this->loadingStates = true;
            $this->state_id = '';
            $this->city_id = '';
            $this->states = State::where('country_id', $this->country_id)->orderBy('name')->get();
            $this->cities = [];
            $this->statesLoaded = true;
            $this->citiesLoaded = false;
            $this->loadingStates = false;
        }
    }
    
    public function loadCities()
    {
        if ($this->state_id) {
            $this->loadingCities = true;
            $this->city_id = '';
            $this->cities = City::where('state_id', $this->state_id)->orderBy('name')->get();
            $this->citiesLoaded = true;
            $this->loadingCities = false;
        }
    }

    public function switchTab($tab)
    {
        $this->currentTab = $tab;
    }

    public function saveBasic()
    {
        $basicRules = [
            'firstname' => 'required|string|max:255',
            'middlename' => 'nullable|string|max:255',
            'surname' => 'required|string|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:6',
            'gender' => 'required|in:male,female',
            'marital_status' => 'required|in:single,married,divorced,widowed,other',
            'dob' => 'required|date',
            'role_id' => 'required|exists:roles,id',
            'phone' => 'required|string|max:20',
        ];

        if ($this->staffId) {
            $basicRules['email'] = 'required|email|unique:users,email,' . $this->staffId;
            unset($basicRules['password']);
        }

        $this->validate($basicRules);

        try {
            $data = [
                'firstname' => $this->firstname,
                'middlename' => $this->middlename,
                'surname' => $this->surname,
                'email' => $this->email,
                'gender' => $this->gender,
                'marital_status' => $this->marital_status,
                'dob' => $this->dob,
                'role_id' => $this->role_id,
                'phone' => $this->phone,
                'active' => $this->active,
            ];

            if (!empty($this->password)) {
                $data['password'] = $this->password;
            }

            if ($this->profile_photo && is_object($this->profile_photo)) {
                $data['profile_photo'] = $this->profile_photo->store('profile_photos', 'public');
            }

            $staffService = app(StaffService::class);

            if ($this->staffId) {
                $staff = User::findOrFail($this->staffId);
                $staffService->updateStaff($staff, $data);
                $message = 'Basic information updated successfully';
            } else {
                $staff = $staffService->createStaff($data);
                $this->staffId = $staff->id;
                $message = 'Staff created successfully';
            }

            $this->showToast('success', $message, 'Staff Information');
            $this->currentTab = 'contact';

        } catch (\Exception $e) {
            $this->showToast('error', 'Error: ' . $e->getMessage(), 'Staff Information');
        }
    }

    public function saveContact()
    {
        if (!$this->staffId) {
            $this->showToast('error', 'Please complete basic information first', 'Staff Information');
            return;
        }

        $contactRules = [
            'address' => 'nullable|string',
            'country_id' => 'nullable|integer',
            'state_id' => 'nullable|integer',
            'city_id' => 'nullable|integer',
        ];

        $this->validate($contactRules);

        try {
            $staff = User::findOrFail($this->staffId);
            $staff->update([
                'address' => $this->address,
                'country_id' => $this->country_id ?: null,
                'state_id' => $this->state_id ?: null,
                'city_id' => $this->city_id ?: null,
            ]);

            $this->showToast('success', 'Contact information updated successfully', 'Staff Information');
            $this->currentTab = 'nok';

        } catch (\Exception $e) {
            $this->showToast('error', 'Error: ' . $e->getMessage(), 'Staff Information');
        }
    }

    public function saveNok()
    {
        if (!$this->staffId) {
            $this->showToast('error', 'Please complete basic information first', 'Staff Information');
            return;
        }

        $nokRules = [
            'nok_name' => 'nullable|string|max:255',
            'nok_phone' => 'nullable|string|max:20',
            'nok_relationship' => 'nullable|string|max:255',
            'nok_address' => 'nullable|string',
        ];

        $this->validate($nokRules);

        try {
            $staff = User::findOrFail($this->staffId);
            $staff->update([
                'nok_name' => $this->nok_name,
                'nok_phone' => $this->nok_phone,
                'nok_relationship' => $this->nok_relationship,
                'nok_address' => $this->nok_address,
            ]);

            session()->flash('toast', [
                'type' => 'success',
                'message' => 'Staff registration completed successfully'
            ]);

            return redirect()->route('staff.index');

        } catch (\Exception $e) {
            session()->flash('toast', [
                'type' => 'error',
                'message' => 'Error: ' . $e->getMessage()
            ]);
        }
    }

    public function deleteStaff()
    {
        if (!$this->staffId) return;

        try {
            $staff = User::findOrFail($this->staffId);
            $staffName = $staff->name;
            
            app(StaffService::class)->deleteStaff($staff);
            
            session()->flash('toast', [
                'type' => 'success',
                'message' => "Staff {$staffName} deleted successfully"
            ]);
            
            return redirect()->route('staff.index');
        } catch (\Exception $e) {
            session()->flash('toast', [
                'type' => 'error',
                'message' => 'Failed to delete staff: ' . $e->getMessage()
            ]);
        }
    }

    public function setCustomPassword()
    {
        if (!$this->staffId) return;

        $this->validate([
            'new_password' => 'required|min:6',
            'confirm_password' => 'required|same:new_password',
        ]);

        try {
            $staff = User::findOrFail($this->staffId);
            $staff->update(['password' => \Illuminate\Support\Facades\Hash::make($this->new_password)]);
            
            $this->new_password = '';
            $this->confirm_password = '';
            
            $this->showToast('success', 'Custom password set successfully', 'Staff Security');
        } catch (\Exception $e) {
            $this->showToast('error', 'Failed to set password: ' . $e->getMessage(), 'Staff Security');
        }
    }

    public function toggleStaffStatus()
    {
        if (!$this->staffId) return;

        try {
            $staff = User::findOrFail($this->staffId);
            $newStatus = !$staff->active;
            $staff->update(['active' => $newStatus]);
            $this->active = $newStatus;
            
            $status = $newStatus ? 'activated' : 'blocked';
            $this->showToast('success', "Staff access {$status} successfully", 'Staff Security');
        } catch (\Exception $e) {
            $this->showToast('error', 'Failed to update staff status: ' . $e->getMessage(), 'Staff Security');
        }
    }

    public function render()
    {
        $roles = Role::orderBy('display_name')->get();
        return view('livewire.staff-form', compact('roles'));
    }
}