<?php

namespace App\Http\Controllers;

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

class PartyController extends Controller
{
    /**
     * Display a listing of parties.
     */
    public function index(Request $request): View
    {
        $query = Party::with('account');

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

        // Search
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                  ->orWhere('name', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%")
                  ->orWhere('city', 'like', "%{$search}%");
            });
        }

        // Only active
        if ($request->boolean('active_only', true)) {
            $query->where('is_active', true);
        }

        $parties = $query->orderBy('name')->get();

        $types = Party::TYPES;

        return view('parties.index', compact('parties', 'types'));
    }

    /**
     * Display purchase parties (suppliers).
     */
    public function purchaseParties(Request $request): View
    {
        $query = Party::suppliers()->with('account');

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                  ->orWhere('name', 'like', "%{$search}%");
            });
        }

        $parties = $query->where('is_active', true)->orderBy('name')->get();

        return view('parties.purchase', compact('parties'));
    }

    /**
     * Display sale parties (customers).
     */
    public function saleParties(Request $request): View
    {
        $query = Party::customers()->with('account');

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('code', 'like', "%{$search}%")
                  ->orWhere('name', 'like', "%{$search}%");
            });
        }

        $parties = $query->where('is_active', true)->orderBy('name')->get();

        return view('parties.sale', compact('parties'));
    }

    /**
     * Show the form for creating a new party.
     */
    public function create(): View
    {
        $types = Party::TYPES;
        return view('parties.create', compact('types'));
    }

    /**
     * Store a newly created party.
     */
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'type' => 'required|in:customer,supplier,both',
            'phone' => 'nullable|string|max:20',
            'mobile' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:100',
            'address' => 'nullable|string|max:255',
            'city' => 'nullable|string|max:50',
            'ntn' => 'nullable|string|max:50',
            'cnic' => 'nullable|string|max:20',
            'credit_limit' => 'nullable|numeric|min:0',
            'credit_days' => 'nullable|integer|min:0',
            'opening_balance' => 'nullable|numeric|min:0',
            'opening_type' => 'nullable|in:debit,credit',
        ]);

        // Generate code
        $validated['code'] = Party::generateCode($validated['type']);
        $validated['opening_balance'] = $validated['opening_balance'] ?? 0;
        $validated['opening_type'] = $validated['opening_type'] ?? 'debit';
        $validated['current_balance'] = $validated['opening_balance'];
        $validated['is_active'] = true;

        Party::create($validated);

        return redirect()->route('parties.index')
            ->with('success', 'Party created successfully.');
    }

    /**
     * Display the specified party.
     */
    public function show(Party $party): View
    {
        $party->load(['account', 'purchases', 'sales']);
        
        return view('parties.show', compact('party'));
    }

    /**
     * Show the form for editing the specified party.
     */
    public function edit(Party $party): View
    {
        $types = Party::TYPES;
        return view('parties.edit', compact('party', 'types'));
    }

    /**
     * Update the specified party.
     */
    public function update(Request $request, Party $party): RedirectResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:100',
            'type' => 'required|in:customer,supplier,both',
            'phone' => 'nullable|string|max:20',
            'mobile' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:100',
            'address' => 'nullable|string|max:255',
            'city' => 'nullable|string|max:50',
            'ntn' => 'nullable|string|max:50',
            'cnic' => 'nullable|string|max:20',
            'credit_limit' => 'nullable|numeric|min:0',
            'credit_days' => 'nullable|integer|min:0',
            'opening_balance' => 'nullable|numeric|min:0',
            'opening_type' => 'nullable|in:debit,credit',
            'is_active' => 'boolean',
        ]);

        $validated['is_active'] = $request->boolean('is_active', true);

        $party->update($validated);

        return redirect()->route('parties.index')
            ->with('success', 'Party updated successfully.');
    }

    /**
     * Remove the specified party.
     */
    public function destroy(Party $party): RedirectResponse
    {
        // Check if party has transactions
        if ($party->purchases()->exists() || $party->sales()->exists()) {
            return redirect()->route('parties.index')
                ->with('error', 'Cannot delete party with transactions. Deactivate it instead.');
        }

        // Delete associated account if exists
        if ($party->account) {
            $party->account->delete();
        }

        $party->delete();

        return redirect()->route('parties.index')
            ->with('success', 'Party deleted successfully.');
    }

    /**
     * Get party balance via AJAX
     */
    public function getBalance(Party $party)
    {
        return response()->json([
            'balance' => $party->current_balance,
            'opening_balance' => $party->opening_balance,
            'opening_type' => $party->opening_type,
        ]);
    }
}
