<?php

namespace App\Http\Controllers;

use App\Models\Organization;
use App\Models\LeadershipPosition;
use App\Models\LeadershipAssignment;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;

/**
 * LeadershipPositionController
 *
 * Handles CRUD operations for leadership positions and assignments.
 * Only accessible by users with Super Manager or Manager roles.
 */
class LeadershipPositionController extends Controller
{
    /**
     * Display a listing of leadership positions.
     */
    public function index(): View
    {
        abort_unless(auth()->user()->can('view leadership positions'), 403,
            'You do not have permission to view leadership positions.');

        $organizations = Organization::with(['leadershipPositions.currentAssignment.user'])
            ->whereHas('leadershipPositions')
            ->orWhereDoesntHave('leadershipPositions')
            ->get();

        $positions = LeadershipPosition::with(['organization', 'currentAssignment.user', 'parentPosition'])
            ->withCount('childPositions')
            ->orderBy('organization_id')
            ->orderBy('hierarchy_level')
            ->paginate(20);

        return view('organization.leadership-positions.index', compact('positions', 'organizations'));
    }

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

        $organizations = Organization::orderBy('name')->get();
        $positions = LeadershipPosition::orderBy('title')->get();
        $hierarchyLevels = LeadershipPosition::HIERARCHY_LEVELS;

        return view('organization.leadership-positions.create', compact('organizations', 'positions', 'hierarchyLevels'));
    }

    /**
     * Store a newly created leadership position in storage.
     */
    public function store(Request $request): RedirectResponse
    {
        abort_unless(auth()->user()->can('create leadership positions'), 403,
            'You do not have permission to create leadership positions.');

        $validated = $request->validate([
            'organization_id' => 'required|exists:organizations,id',
            'title' => 'required|string|max:191',
            'hierarchy_level' => 'required|in:bod,chairman,ceo,c_suite,middle_management,first_line_management,frontline',
            'parent_position_id' => 'nullable|exists:leadership_positions,id',
            'description' => 'nullable|string',
        ], [
            'organization_id.required' => 'Please select an organization.',
            'organization_id.exists' => 'Selected organization does not exist.',
            'title.required' => 'Position title is required.',
            'hierarchy_level.required' => 'Please select a hierarchy level.',
            'hierarchy_level.in' => 'Invalid hierarchy level selected.',
        ]);

        // XSS Prevention
        $validated['title'] = strip_tags($validated['title']);
        $validated['description'] = strip_tags($validated['description'] ?? '');

        // Check for circular hierarchy if parent is set
        if (!empty($validated['parent_position_id'])) {
            $parentPosition = LeadershipPosition::find($validated['parent_position_id']);

            // Ensure parent belongs to same organization
            if ($parentPosition->organization_id != $validated['organization_id']) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', 'Parent position must belong to the same organization.');
            }
        }

        LeadershipPosition::create($validated);

        return redirect()
            ->route('organization.leadership-positions.index')
            ->with('success', 'Leadership position created successfully!');
    }

    /**
     * Show the form for editing the specified leadership position.
     */
    public function edit(LeadershipPosition $leadershipPosition): View
    {
        abort_unless(auth()->user()->can('edit leadership positions'), 403,
            'You do not have permission to edit leadership positions.');

        $organizations = Organization::orderBy('name')->get();
        $positions = LeadershipPosition::where('id', '!=', $leadershipPosition->id)
            ->where('organization_id', $leadershipPosition->organization_id)
            ->orderBy('title')
            ->get();
        $hierarchyLevels = LeadershipPosition::HIERARCHY_LEVELS;

        return view('organization.leadership-positions.edit', compact('leadershipPosition', 'organizations', 'positions', 'hierarchyLevels'));
    }

    /**
     * Update the specified leadership position in storage.
     */
    public function update(Request $request, LeadershipPosition $leadershipPosition): RedirectResponse
    {
        abort_unless(auth()->user()->can('edit leadership positions'), 403,
            'You do not have permission to edit leadership positions.');

        $validated = $request->validate([
            'organization_id' => 'required|exists:organizations,id',
            'title' => 'required|string|max:191',
            'hierarchy_level' => 'required|in:bod,chairman,ceo,c_suite,middle_management,first_line_management,frontline',
            'parent_position_id' => 'nullable|exists:leadership_positions,id',
            'description' => 'nullable|string',
        ], [
            'organization_id.required' => 'Please select an organization.',
            'title.required' => 'Position title is required.',
            'hierarchy_level.required' => 'Please select a hierarchy level.',
        ]);

        // XSS Prevention
        $validated['title'] = strip_tags($validated['title']);
        $validated['description'] = strip_tags($validated['description'] ?? '');

        // Check for circular hierarchy
        if (!empty($validated['parent_position_id'])) {
            $parentPosition = LeadershipPosition::find($validated['parent_position_id']);

            // Cannot be parent of self
            if ($parentPosition->id === $leadershipPosition->id) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', 'A position cannot report to itself.');
            }

            // Check if this would create a circular relationship
            if ($leadershipPosition->wouldCreateCircularRelationship($parentPosition)) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', 'This would create a circular reporting relationship.');
            }

            // Ensure parent belongs to same organization
            if ($parentPosition->organization_id != $validated['organization_id']) {
                return redirect()
                    ->back()
                    ->withInput()
                    ->with('error', 'Parent position must belong to the same organization.');
            }
        }

        $leadershipPosition->update($validated);

        return redirect()
            ->route('organization.leadership-positions.index')
            ->with('success', 'Leadership position updated successfully!');
    }

    /**
     * Remove the specified leadership position from storage.
     */
    public function destroy(LeadershipPosition $leadershipPosition): RedirectResponse
    {
        abort_unless(auth()->user()->can('delete leadership positions'), 403,
            'You do not have permission to delete leadership positions.');

        // Check for child positions
        if ($leadershipPosition->childPositions()->exists()) {
            return redirect()
                ->route('organization.leadership-positions.index')
                ->with('error', 'Cannot delete position with child positions. Reassign children first.');
        }

        // Check for current assignments
        if ($leadershipPosition->currentAssignment) {
            return redirect()
                ->route('organization.leadership-positions.index')
                ->with('error', 'Cannot delete position with current assignment. End assignment first.');
        }

        $leadershipPosition->delete();

        return redirect()
            ->route('organization.leadership-positions.index')
            ->with('success', 'Leadership position deleted successfully!');
    }

    /**
     * Show the form for assigning a user to a position.
     */
    public function assign(LeadershipPosition $leadershipPosition): View
    {
        abort_unless(auth()->user()->can('assign leadership'), 403,
            'You do not have permission to assign leadership positions.');

        $users = \App\Models\User::orderBy('name')->get();
        $currentAssignment = $leadershipPosition->currentAssignment;
        $pastAssignments = $leadershipPosition->assignments()
            ->where('is_current', false)
            ->with('user')
            ->orderBy('end_date', 'desc')
            ->get();

        return view('organization.leadership-positions.assign', compact('leadershipPosition', 'users', 'currentAssignment', 'pastAssignments'));
    }

    /**
     * Assign a user to a leadership position.
     */
    public function storeAssignment(Request $request, LeadershipPosition $leadershipPosition): RedirectResponse
    {
        abort_unless(auth()->user()->can('assign leadership'), 403,
            'You do not have permission to assign leadership positions.');

        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after:start_date',
        ], [
            'user_id.required' => 'Please select a user.',
            'user_id.exists' => 'Selected user does not exist.',
            'start_date.required' => 'Start date is required.',
            'start_date.date' => 'Please enter a valid start date.',
            'end_date.after' => 'End date must be after start date.',
        ]);

        // End current assignment if exists
        if ($leadershipPosition->currentAssignment) {
            $currentAssignment = $leadershipPosition->currentAssignment;
            $currentAssignment->is_current = false;
            $currentAssignment->end_date = now()->toDateString();
            $currentAssignment->save();
        }

        // Create new assignment
        LeadershipAssignment::create([
            'leadership_position_id' => $leadershipPosition->id,
            'user_id' => $validated['user_id'],
            'start_date' => $validated['start_date'],
            'end_date' => $validated['end_date'] ?? null,
            'is_current' => true,
        ]);

        return redirect()
            ->route('organization.leadership-positions.index')
            ->with('success', 'User assigned to position successfully!');
    }

    /**
     * End a leadership assignment.
     */
    public function unassign(LeadershipAssignment $assignment): RedirectResponse
    {
        abort_unless(auth()->user()->can('assign leadership'), 403,
            'You do not have permission to end leadership assignments.');

        if (!$assignment->is_current) {
            return redirect()
                ->route('organization.leadership-positions.index')
                ->with('error', 'This assignment is already ended.');
        }

        $assignment->end();

        return redirect()
            ->route('organization.leadership-positions.index')
            ->with('success', 'Leadership assignment ended successfully!');
    }
}
