<?php

namespace App\Http\Controllers;

use App\Http\Requests\StorePartyRequest;
use App\Models\Party;
use App\Services\ActivityLogService;
use Illuminate\Http\Request;

class PartyController extends Controller
{
    public function __construct(protected ActivityLogService $log) {}

    public function suppliers(Request $request)
    {
        $suppliers = Party::suppliers()
            ->when($request->search, fn ($q) => $q->where('name', 'like', "%{$request->search}%"))
            ->orderBy('name')
            ->paginate(20)
            ->withQueryString();
        return view('parties.supplier', compact('suppliers'));
    }

    public function customers(Request $request)
    {
        $customers = Party::customers()
            ->when($request->search, fn ($q) => $q->where('name', 'like', "%{$request->search}%"))
            ->orderBy('name')
            ->paginate(20)
            ->withQueryString();
        return view('parties.customer', compact('customers'));
    }

    public function store(StorePartyRequest $request)
    {
        $data = $request->validated();
        $typeLetter = match($data['type']) { 'supplier' => 'SUP', 'customer' => 'CUS', 'both' => 'PRT' };
        $data['code'] = $typeLetter . '-' . str_pad(Party::withTrashed()->count() + 1, 4, '0', STR_PAD_LEFT);
        $party = Party::create($data);
        $this->log->log('created', 'party', $party, "{$party->name} ({$party->type}) created");
        return back()->with('success', "{$party->name} created successfully.");
    }

    public function show(Party $party)
    {
        $party->loadCount(['purchases', 'sales', 'vouchers']);
        return view('parties.show', compact('party'));
    }

    public function edit(Party $party)
    {
        return view('parties.form', compact('party'));
    }

    public function update(StorePartyRequest $request, Party $party)
    {
        $old = $party->toArray();
        $party->update($request->validated());
        $this->log->log('updated', 'party', $party, "{$party->name} updated", $old, $party->toArray());
        $route = $party->type === 'customer' ? 'customer.index' : 'supplier.index';
        return redirect()->route($route)->with('success', "{$party->name} updated.");
    }

    public function destroy(Party $party)
    {
        $name = $party->name;
        $type = $party->type;
        $party->delete();
        $this->log->logAction('deleted', 'party', Party::class, $party->id, "{$name} ({$type}) deleted");
        return back()->with('success', "{$name} deleted.");
    }

    public function restore($id)
    {
        $party = Party::onlyTrashed()->findOrFail($id);
        $party->restore();
        $this->log->log('restored', 'party', $party, "{$party->name} restored");
        return back()->with('success', "{$party->name} restored.");
    }

    public function forceDelete($id)
    {
        $party = Party::onlyTrashed()->findOrFail($id);
        $name = $party->name;
        $party->forceDelete();
        $this->log->logAction('force_deleted', 'party', Party::class, $id, "{$name} permanently deleted");
        return back()->with('success', "{$name} permanently deleted.");
    }
}
