<?php

namespace App\Http\Controllers;

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

/**
 * OrganizationController
 *
 * Handles CRUD operations for organization details.
 * Only accessible by users with Super Manager or Manager roles.
 */
class OrganizationController extends Controller
{
    /**
     * Display the organization module landing page.
     */
    public function landing(): \Illuminate\View\View
    {
        return view('organization.index');
    }

    /**
     * Display a listing of organizations.
     */
    public function index(): View
    {
        abort_unless(auth()->user()->can('view organizations'), 403,
            'You do not have permission to view organizations.');

        $organizations = Organization::withCount([
            'leadershipPositions',
            'electionCycles',
            'votingProcedures',
            'staffHistories'
        ])->latest()->paginate(15);

        return view('organization.details.index', compact('organizations'));
    }

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

        return view('organization.details.create');
    }

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

        $validated = $request->validate([
            'name' => 'required|string|max:191|unique:organizations,name',
            'short_name' => 'required|string|max:191',
            'country' => 'required|string|max:191',
            'city' => 'required|string|max:191',
            'postal_address' => 'required|string',
            'postal_code' => 'required|string|max:20',
            'physical_address' => 'required|string',
            'email' => 'required|email|max:191',
            'hotline' => 'required|string|max:50',
            'year_of_formation' => 'required|integer|min:1800|max:' . date('Y'),
            'social_media_links' => 'nullable|array',
            'social_media_links.whatsapp' => 'nullable|url|max:191',
            'social_media_links.facebook' => 'nullable|url|max:191',
            'social_media_links.twitter' => 'nullable|url|max:191',
            'social_media_links.tiktok' => 'nullable|url|max:191',
            'social_media_links.linkedin' => 'nullable|url|max:191',
            'social_media_links.instagram' => 'nullable|url|max:191',
            'social_media_links.youtube' => 'nullable|url|max:191',
        ], [
            'name.required' => 'Organization name is required.',
            'name.unique' => 'An organization with this name already exists.',
            'short_name.required' => 'Short name is required.',
            'country.required' => 'Country is required.',
            'city.required' => 'City is required.',
            'email.email' => 'Please enter a valid email address.',
            'year_of_formation.min' => 'Year of formation must be at least 1800.',
            'year_of_formation.max' => 'Year of formation cannot be in the future.',
        ]);

        // XSS Prevention
        $validated['name'] = strip_tags($validated['name']);
        $validated['short_name'] = strip_tags($validated['short_name']);
        $validated['country'] = strip_tags($validated['country']);
        $validated['city'] = strip_tags($validated['city']);
        $validated['postal_address'] = strip_tags($validated['postal_address']);
        $validated['physical_address'] = strip_tags($validated['physical_address']);

        // Filter social media links
        if (isset($validated['social_media_links'])) {
            $validated['social_media_links'] = array_filter($validated['social_media_links']);
        }

        Organization::create($validated);

        return redirect()
            ->route('organization.details.index')
            ->with('success', 'Organization created successfully!');
    }

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

        $organization->load([
            'leadershipPositions' => fn($q) => $q->orderBy('hierarchy_level'),
            'electionCycles' => fn($q) => $q->latest('start_date')->limit(5),
            'votingProcedures' => fn($q) => $q->latest()->limit(5),
            'staffHistories' => fn($q) => $q->latest()->limit(5),
        ]);

        $organization->loadCount([
            'leadershipPositions',
            'electionCycles',
            'votingProcedures',
            'staffHistories',
            'leadershipHistories',
        ]);

        $currentLeadership = $organization->getCurrentLeadershipAssignments();

        return view('organization.details.show', compact('organization', 'currentLeadership'));
    }

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

        return view('organization.details.edit', compact('organization'));
    }

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

        $validated = $request->validate([
            'name' => 'required|string|max:191|unique:organizations,name,' . $organization->id,
            'short_name' => 'required|string|max:191',
            'country' => 'required|string|max:191',
            'city' => 'required|string|max:191',
            'postal_address' => 'required|string',
            'postal_code' => 'required|string|max:20',
            'physical_address' => 'required|string',
            'email' => 'required|email|max:191',
            'hotline' => 'required|string|max:50',
            'year_of_formation' => 'required|integer|min:1800|max:' . date('Y'),
            'social_media_links' => 'nullable|array',
            'social_media_links.whatsapp' => 'nullable|url|max:191',
            'social_media_links.facebook' => 'nullable|url|max:191',
            'social_media_links.twitter' => 'nullable|url|max:191',
            'social_media_links.tiktok' => 'nullable|url|max:191',
            'social_media_links.linkedin' => 'nullable|url|max:191',
            'social_media_links.instagram' => 'nullable|url|max:191',
            'social_media_links.youtube' => 'nullable|url|max:191',
        ], [
            'name.required' => 'Organization name is required.',
            'name.unique' => 'An organization with this name already exists.',
            'email.email' => 'Please enter a valid email address.',
            'year_of_formation.min' => 'Year of formation must be at least 1800.',
            'year_of_formation.max' => 'Year of formation cannot be in the future.',
        ]);

        // XSS Prevention
        $validated['name'] = strip_tags($validated['name']);
        $validated['short_name'] = strip_tags($validated['short_name']);
        $validated['country'] = strip_tags($validated['country']);
        $validated['city'] = strip_tags($validated['city']);
        $validated['postal_address'] = strip_tags($validated['postal_address']);
        $validated['physical_address'] = strip_tags($validated['physical_address']);

        // Filter social media links
        if (isset($validated['social_media_links'])) {
            $validated['social_media_links'] = array_filter($validated['social_media_links']);
        }

        $organization->update($validated);

        return redirect()
            ->route('organization.details.index')
            ->with('success', 'Organization updated successfully!');
    }

    /**
     * Remove the specified organization from storage (soft delete).
     */
    public function destroy(Organization $organization): RedirectResponse
    {
        abort_unless(auth()->user()->can('delete organizations'), 403,
            'You do not have permission to delete organizations.');

        // Check for related records before deleting
        if ($organization->leadershipPositions()->exists()) {
            return redirect()
                ->route('organization.details.index')
                ->with('error', 'Cannot delete organization with existing leadership positions. Remove them first.');
        }

        if ($organization->electionCycles()->exists()) {
            return redirect()
                ->route('organization.details.index')
                ->with('error', 'Cannot delete organization with existing election cycles. Remove them first.');
        }

        if ($organization->votingProcedures()->exists()) {
            return redirect()
                ->route('organization.details.index')
                ->with('error', 'Cannot delete organization with existing voting procedures. Remove them first.');
        }

        if ($organization->staffHistories()->exists()) {
            return redirect()
                ->route('organization.details.index')
                ->with('error', 'Cannot delete organization with existing staff history records. Remove them first.');
        }

        $organization->delete();

        return redirect()
            ->route('organization.details.index')
            ->with('success', 'Organization deleted successfully!');
    }
}
