<?php

namespace App\Http\Controllers\Membership\Admin;

use App\Http\Controllers\Controller;
use App\Models\MembershipCategory;
use App\Models\SubscriptionFee;
use App\Models\ContributionFee;
use App\Models\ContributionPenalty;
use App\Services\ContributionService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class MembershipCategoryController extends Controller
{
    protected ContributionService $contributionService;

    public function __construct(ContributionService $contributionService)
    {
        $this->contributionService = $contributionService;
    }

    /**
     * Display all membership categories.
     */
    public function index()
    {
        abort_unless(auth()->user()->can('view membership categories'), 403);

        $categories = MembershipCategory::withCount('members')
            ->with(['subscriptionFees', 'contributionFees'])
            ->ordered()
            ->get();

        return view('membership.admin.categories.index', compact('categories'));
    }

    /**
     * Show form to create a new category.
     */
    public function create()
    {
        abort_unless(auth()->user()->can('create membership categories'), 403);

        return view('membership.admin.categories.create');
    }

    /**
     * Store a new membership category.
     */
    public function store(Request $request)
    {
        abort_unless(auth()->user()->can('create membership categories'), 403);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:191|unique:membership_categories,name',
            'description' => 'nullable|string|max:2000',
            'benefits' => 'nullable|array',
            'is_active' => 'boolean',
            'theme_color' => 'nullable|string|max:50',
            'icon' => 'nullable|string|max:100',
        ], [
            'name.required' => 'Category name is required.',
            'name.unique' => 'A category with this name already exists.',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $validated = $validator->validated();
        $validated['name'] = strip_tags($validated['name']);
        $validated['slug'] = Str::slug($validated['name']);
        $validated['description'] = strip_tags($validated['description'] ?? '');

        MembershipCategory::create($validated);

        return redirect()->route('admin.membership-categories.index')
            ->with('success', 'Membership category created successfully.');
    }

    /**
     * Display category details.
     */
    public function show(MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('view membership categories'), 403);

        $membershipCategory->load([
            'subscriptionFees',
            'contributionFees',
            'penalties',
        ]);

        $statistics = [
            'total_members' => $membershipCategory->members()->count(),
            'active_members' => $membershipCategory->members()->where('status', 'active')->count(),
        ];

        return view('membership.admin.categories.show', compact('membershipCategory', 'statistics'));
    }

    /**
     * Show form to edit a category.
     */
    public function edit(MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('edit membership categories'), 403);

        return view('membership.admin.categories.edit', compact('membershipCategory'));
    }

    /**
     * Update a membership category.
     */
    public function update(Request $request, MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('edit membership categories'), 403);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:191|unique:membership_categories,name,' . $membershipCategory->id,
            'description' => 'nullable|string|max:2000',
            'benefits' => 'nullable|array',
            'is_active' => 'boolean',
            'theme_color' => 'nullable|string|max:50',
            'icon' => 'nullable|string|max:100',
        ], [
            'name.required' => 'Category name is required.',
            'name.unique' => 'A category with this name already exists.',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $validated = $validator->validated();
        $validated['name'] = strip_tags($validated['name']);
        $validated['slug'] = Str::slug($validated['name']);
        $validated['description'] = strip_tags($validated['description'] ?? '');

        $membershipCategory->update($validated);

        return redirect()->route('admin.membership-categories.show', $membershipCategory)
            ->with('success', 'Membership category updated successfully.');
    }

    /**
     * Delete a membership category.
     */
    public function destroy(MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('delete membership categories'), 403);

        if (!$membershipCategory->canBeDeleted()) {
            return redirect()->back()
                ->withErrors(['error' => 'Cannot delete category with assigned members.']);
        }

        $membershipCategory->delete();

        return redirect()->route('admin.membership-categories.index')
            ->with('success', 'Membership category deleted.');
    }

    /**
     * Display subscription fees for a category.
     */
    public function subscriptionFees(MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('view subscription fees'), 403);

        $fees = $membershipCategory->subscriptionFees()
            ->with('creator')
            ->latest()
            ->get();

        return view('membership.admin.categories.subscription-fees', compact('membershipCategory', 'fees'));
    }

    /**
     * Store a subscription fee.
     */
    public function storeSubscriptionFee(Request $request, MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('create subscription fees'), 403);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:191',
            'description' => 'nullable|string|max:500',
            'amount' => 'required|numeric|min:0',
            'currency' => 'required|in:USD,SSP,KES,UGX',
            'billing_cycle' => 'required|in:one_time,monthly,quarterly,biannual,annual',
            'is_active' => 'boolean',
            'is_default' => 'boolean',
            'effective_from' => 'nullable|date',
            'effective_until' => 'nullable|date|after_or_equal:effective_from',
        ], [
            'name.required' => 'Fee name is required.',
            'amount.required' => 'Amount is required.',
            'amount.numeric' => 'Amount must be a valid number.',
            'amount.min' => 'Amount must be greater than or equal to zero.',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $validated = $validator->validated();
        $validated['membership_category_id'] = $membershipCategory->id;
        $validated['created_by'] = auth()->id();
        $validated['name'] = strip_tags($validated['name']);

        SubscriptionFee::create($validated);

        return redirect()->route('admin.membership-categories.subscription-fees', $membershipCategory)
            ->with('success', 'Subscription fee created successfully.');
    }

    /**
     * Display contribution fees for a category.
     */
    public function contributionFees(MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('view contribution fees'), 403);

        $fees = $membershipCategory->contributionFees()
            ->with('creator')
            ->latest()
            ->get();

        $penalties = $membershipCategory->penalties()
            ->with('creator')
            ->latest()
            ->get();

        return view('membership.admin.categories.contribution-fees', compact('membershipCategory', 'fees', 'penalties'));
    }

    /**
     * Store a contribution fee.
     */
    public function storeContributionFee(Request $request, MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('create contribution fees'), 403);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:191',
            'description' => 'nullable|string|max:500',
            'amount' => 'required|numeric|min:0',
            'currency' => 'required|in:USD,SSP,KES,UGX',
            'cycle' => 'required|in:monthly,quarterly,biannual,annual',
            'is_optional' => 'boolean',
            'is_active' => 'boolean',
            'due_day' => 'required|integer|min:1|max:28',
            'effective_from' => 'nullable|date',
            'effective_until' => 'nullable|date|after_or_equal:effective_from',
        ], [
            'name.required' => 'Fee name is required.',
            'amount.required' => 'Amount is required.',
            'amount.numeric' => 'Amount must be a valid number.',
            'amount.min' => 'Amount must be greater than or equal to zero.',
            'due_day.required' => 'Due day is required.',
            'due_day.min' => 'Due day must be between 1 and 28.',
            'due_day.max' => 'Due day must be between 1 and 28.',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $validated = $validator->validated();
        $validated['membership_category_id'] = $membershipCategory->id;
        $validated['created_by'] = auth()->id();
        $validated['name'] = strip_tags($validated['name']);

        ContributionFee::create($validated);

        return redirect()->route('admin.membership-categories.contribution-fees', $membershipCategory)
            ->with('success', 'Contribution fee created successfully.');
    }

    /**
     * Store a penalty configuration.
     */
    public function storePenalty(Request $request, MembershipCategory $membershipCategory)
    {
        abort_unless(auth()->user()->can('create contribution fees'), 403);

        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:191',
            'description' => 'nullable|string|max:500',
            'type' => 'required|in:fixed,percentage',
            'amount' => 'required_if:type,fixed|numeric|min:0',
            'percentage' => 'required_if:type,percentage|numeric|min:0|max:100',
            'grace_period_days' => 'required|integer|min:0',
            'apply_recurring' => 'boolean',
            'is_active' => 'boolean',
            'max_penalty_days' => 'nullable|integer|min:1',
        ], [
            'name.required' => 'Penalty name is required.',
            'type.required' => 'Penalty type is required.',
            'amount.required_if' => 'Amount is required for fixed penalty type.',
            'percentage.required_if' => 'Percentage is required for percentage penalty type.',
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        $validated = $validator->validated();
        $validated['membership_category_id'] = $membershipCategory->id;
        $validated['created_by'] = auth()->id();
        $validated['name'] = strip_tags($validated['name']);

        ContributionPenalty::create($validated);

        return redirect()->route('admin.membership-categories.contribution-fees', $membershipCategory)
            ->with('success', 'Penalty configuration created successfully.');
    }
}
