<?php

namespace App\Http\Controllers;

use App\Models\StaffHistory;
use App\Models\StaffAchievement;
use App\Models\Organization;
use App\Http\Requests\StoreStaffHistoryRequest;
use App\Http\Requests\UpdateStaffHistoryRequest;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use Illuminate\Support\Facades\Storage;

/**
 * StaffHistoryController
 *
 * Handles CRUD operations for staff employment history and achievements.
 * Only accessible by users with Super Manager or Manager roles.
 */
class StaffHistoryController extends Controller
{
    /**
     * Display a listing of staff history records.
     */
    public function index(Request $request): View
    {
        abort_unless(auth()->user()->can('view staff history'), 403,
            'You do not have permission to view staff history.');

        $query = StaffHistory::with(['organization', 'user', 'achievements'])
            ->withCount('achievements');

        // Filter by organization
        if ($request->filled('organization_id')) {
            $query->where('organization_id', $request->organization_id);
        }

        // Filter by employment status
        if ($request->filled('employment_status')) {
            $query->where('employment_status', $request->employment_status);
        }

        // Filter by date range
        if ($request->filled('start_date') && $request->filled('end_date')) {
            $query->dateRange($request->start_date, $request->end_date);
        }

        // Search by name or position
        if ($request->filled('search')) {
            $query->search($request->search);
        }

        $staffHistories = $query->orderByStartDate()->paginate(20);

        // Get filter options
        $organizations = Organization::orderBy('name')->get();

        return view('organization.staff-history.index', compact('staffHistories', 'organizations'));
    }

    /**
     * Show the form for creating a new staff history record.
     */
    public function create(): View
    {
        abort_unless(auth()->user()->can('create staff history'), 403,
            'You do not have permission to create staff history records.');

        $organizations = Organization::orderBy('name')->get();
        $users = \App\Models\User::orderBy('name')->get();

        return view('organization.staff-history.create', compact('organizations', 'users'));
    }

    /**
     * Store a newly created staff history record in storage.
     */
    public function store(StoreStaffHistoryRequest $request): RedirectResponse
    {
        $validated = $request->validated();

        // XSS Prevention
        $validated['staff_name'] = strip_tags($validated['staff_name']);
        $validated['position'] = strip_tags($validated['position']);
        $validated['termination_reason'] = strip_tags($validated['termination_reason'] ?? '');

        // Handle passport file upload
        if ($request->hasFile('passport')) {
            $validated['passport_path'] = $request->file('passport')
                ->store('staff-passports', 'public');
        }

        // Ensure consistency between status and end date
        if (!empty($validated['employment_end_date'])) {
            $validated['employment_status'] = StaffHistory::STATUS_FORMER;
        } elseif ($validated['employment_status'] === StaffHistory::STATUS_CURRENT) {
            $validated['employment_end_date'] = null;
        }

        StaffHistory::create($validated);

        return redirect()
            ->route('organization.staff-history.index')
            ->with('success', 'Staff record created successfully!');
    }

    /**
     * Display the specified staff history record.
     */
    public function show(StaffHistory $staffHistory): View
    {
        abort_unless(auth()->user()->can('view staff history'), 403,
            'You do not have permission to view staff history.');

        $staffHistory->load(['organization', 'user', 'achievements' => function ($query) {
            $query->orderByDate();
        }]);

        return view('organization.staff-history.show', compact('staffHistory'));
    }

    /**
     * Show the form for editing the specified staff history record.
     */
    public function edit(StaffHistory $staffHistory): View
    {
        abort_unless(auth()->user()->can('edit staff history'), 403,
            'You do not have permission to edit staff history.');

        $organizations = Organization::orderBy('name')->get();
        $users = \App\Models\User::orderBy('name')->get();

        return view('organization.staff-history.edit', compact('staffHistory', 'organizations', 'users'));
    }

    /**
     * Update the specified staff history record in storage.
     */
    public function update(UpdateStaffHistoryRequest $request, StaffHistory $staffHistory): RedirectResponse
    {
        $validated = $request->validated();

        // XSS Prevention
        $validated['staff_name'] = strip_tags($validated['staff_name']);
        $validated['position'] = strip_tags($validated['position']);
        $validated['termination_reason'] = strip_tags($validated['termination_reason'] ?? '');

        // Handle passport file upload - replace existing if new file provided
        if ($request->hasFile('passport')) {
            // Delete old passport if it exists
            if ($staffHistory->hasPassport()) {
                Storage::disk('public')->delete($staffHistory->passport_path);
            }
            // Store new passport
            $validated['passport_path'] = $request->file('passport')
                ->store('staff-passports', 'public');
        }

        // Ensure consistency between status and end date
        if (!empty($validated['employment_end_date'])) {
            $validated['employment_status'] = StaffHistory::STATUS_FORMER;
        } elseif ($validated['employment_status'] === StaffHistory::STATUS_CURRENT) {
            $validated['employment_end_date'] = null;
        }

        $staffHistory->update($validated);

        return redirect()
            ->route('organization.staff-history.index')
            ->with('success', 'Staff record updated successfully!');
    }

    /**
     * Remove the specified staff history record from storage.
     */
    public function destroy(StaffHistory $staffHistory): RedirectResponse
    {
        abort_unless(auth()->user()->can('delete staff history'), 403,
            'You do not have permission to delete staff history.');

        $staffHistory->delete();

        return redirect()
            ->route('organization.staff-history.index')
            ->with('success', 'Staff record deleted successfully!');
    }

    /**
     * Add an achievement to a staff history record.
     */
    public function addAchievement(Request $request, StaffHistory $staffHistory): RedirectResponse
    {
        abort_unless(auth()->user()->can('add staff achievements'), 403,
            'You do not have permission to add staff achievements.');

        $validated = $request->validate([
            'achievement_description' => 'required|string',
            'achievement_date' => 'required|date|before_or_equal:today',
        ], [
            'achievement_description.required' => 'Achievement description is required.',
            'achievement_date.required' => 'Achievement date is required.',
            'achievement_date.before_or_equal' => 'Achievement date cannot be in the future.',
        ]);

        // XSS Prevention
        $validated['achievement_description'] = strip_tags($validated['achievement_description']);

        $staffHistory->addAchievement(
            $validated['achievement_description'],
            $validated['achievement_date']
        );

        return redirect()
            ->route('organization.staff-history.show', $staffHistory)
            ->with('success', 'Achievement added successfully!');
    }

    /**
     * Delete an achievement from a staff history record.
     */
    public function deleteAchievement(StaffAchievement $achievement): RedirectResponse
    {
        abort_unless(auth()->user()->can('add staff achievements'), 403,
            'You do not have permission to manage staff achievements.');

        $staffId = $achievement->staff_history_id;
        $achievement->delete();

        return redirect()
            ->route('organization.staff-history.show', $staffId)
            ->with('success', 'Achievement deleted successfully!');
    }

    /**
     * Delete the passport file from a staff record.
     */
    public function deletePassport(StaffHistory $staffHistory): RedirectResponse
    {
        abort_unless(auth()->user()->can('edit staff history'), 403,
            'You do not have permission to delete staff passports.');

        $staffHistory->deletePassport();

        return redirect()
            ->route('organization.staff-history.edit', $staffHistory)
            ->with('success', 'Passport removed successfully!');
    }
}
