<?php

namespace App\Http\Controllers\Api\V1\Supplier;

use App\Http\Controllers\Controller;
use App\Services\SupplierService;
use App\Services\ResponseService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class SupplierController extends Controller
{
    public function __construct(
        private SupplierService $supplierService,
        private ResponseService $responseService
    ) {}

    // =============================================
    // SUPPLIERS
    // =============================================

    public function index(Request $request): JsonResponse
    {
        $filters = $request->only(['is_active', 'search', 'tenant_id']);
        if (isset($filters['is_active'])) {
            $filters['is_active'] = filter_var($filters['is_active'], FILTER_VALIDATE_BOOLEAN);
        }
        $suppliers = $this->supplierService->getAll($filters);
        return $this->responseService->success($suppliers, 'Suppliers retrieved successfully');
    }

    public function store(Request $request): JsonResponse
    {
        $data = $request->validate([
            'name'                => 'required|string|max:255',
            'company_name'        => 'nullable|string|max:255',
            'contact_person'      => 'nullable|string|max:255',
            'phone'               => 'nullable|string|max:50',
            'email'               => 'nullable|email|max:255',
            'address'             => 'nullable|string',
            'supplier_type'       => 'nullable|in:manufacturer,distributor,wholesaler,local',
            'credit_limit'        => 'nullable|numeric|min:0',
            'payment_terms_days'  => 'nullable|integer|min:0|max:365',
            'opening_balance'     => 'nullable|numeric|min:0',
            'tax_number'          => 'nullable|string|max:50',
            'license_number'      => 'nullable|string|max:100',
            'notes'               => 'nullable|string',
            'is_active'           => 'nullable|boolean',
            'branch_id'           => 'nullable|exists:branches,id',
        ]);

        $data['tenant_id'] = auth()->user()?->tenant_id;

        $supplier = $this->supplierService->create($data);
        return $this->responseService->success($supplier, 'Supplier created successfully', 201);
    }

    public function show(int $id): JsonResponse
    {
        $supplier = $this->supplierService->find($id);
        if (!$supplier) {
            return $this->responseService->error('Supplier not found', 404);
        }
        return $this->responseService->success($supplier, 'Supplier retrieved successfully');
    }

    public function update(Request $request, int $id): JsonResponse
    {
        $data = $request->validate([
            'name'               => 'sometimes|string|max:255',
            'company_name'       => 'nullable|string|max:255',
            'contact_person'     => 'nullable|string|max:255',
            'phone'              => 'nullable|string|max:50',
            'email'              => 'nullable|email|max:255',
            'address'            => 'nullable|string',
            'supplier_type'      => 'nullable|in:manufacturer,distributor,wholesaler,local',
            'credit_limit'       => 'nullable|numeric|min:0',
            'payment_terms_days' => 'nullable|integer|min:0|max:365',
            'tax_number'         => 'nullable|string|max:50',
            'license_number'     => 'nullable|string|max:100',
            'notes'              => 'nullable|string',
            'is_active'          => 'nullable|boolean',
        ]);

        $supplier = $this->supplierService->update($id, $data);
        if (!$supplier) {
            return $this->responseService->error('Supplier not found', 404);
        }
        return $this->responseService->success($supplier, 'Supplier updated successfully');
    }

    public function destroy(int $id): JsonResponse
    {
        try {
            $deleted = $this->supplierService->delete($id);
            if (!$deleted) {
                return $this->responseService->error('Supplier not found', 404);
            }
            return $this->responseService->success(null, 'Supplier deleted successfully');
        } catch (\Exception $e) {
            return $this->responseService->error($e->getMessage(), 422);
        }
    }

    public function summary(Request $request): JsonResponse
    {
        $summary = $this->supplierService->getDashboardSummary(
            $request->integer('branch_id') ?: null
        );
        return $this->responseService->success($summary, 'Supplier summary retrieved successfully');
    }

    // =============================================
    // INVOICES
    // =============================================

    public function invoices(Request $request, int $supplierId): JsonResponse
    {
        $filters = $request->only(['branch_id', 'status', 'payment_type', 'start_date', 'end_date']);
        $invoices = $this->supplierService->getInvoices($supplierId, $filters);
        return $this->responseService->success($invoices, 'Invoices retrieved successfully');
    }

    public function allInvoices(Request $request): JsonResponse
    {
        $filters = $request->only(['branch_id', 'status', 'start_date', 'end_date']);
        $invoices = $this->supplierService->getAllInvoices($filters);
        return $this->responseService->success($invoices, 'All invoices retrieved successfully');
    }

    public function storeInvoice(Request $request, int $supplierId): JsonResponse
    {
        $data = $request->validate([
            'branch_id'          => 'required|exists:branches,id',
            'invoice_number'     => 'nullable|string|max:100',
            'our_reference'      => 'nullable|string|max:100',
            'purchase_order_id'  => 'nullable|exists:purchase_orders,id',
            'invoice_date'       => 'required|date',
            'due_date'           => 'nullable|date',
            'discount_amount'    => 'nullable|numeric|min:0',
            'tax_amount'         => 'nullable|numeric|min:0',
            'payment_type'       => 'required|in:credit,cash',
            'notes'              => 'nullable|string',
            'items'              => 'required|array|min:1',
            'items.*.item_type'  => 'required|in:ingredient,product,other',
            'items.*.ingredient_id' => 'nullable|exists:ingredients,id',
            'items.*.product_id'    => 'nullable|exists:products,id',
            'items.*.description'   => 'required|string|max:255',
            'items.*.quantity'      => 'required|numeric|min:0.001',
            'items.*.bonus_quantity'=> 'nullable|numeric|min:0',
            'items.*.unit'          => 'nullable|string|max:20',
            'items.*.unit_price'    => 'required|numeric|min:0',
            'items.*.batch_number'  => 'nullable|string|max:100',
            'items.*.expiry_date'   => 'nullable|date',
            'items.*.notes'         => 'nullable|string',
        ]);

        $data['supplier_id'] = $supplierId;
        $data['user_id']     = auth()->id();

        $invoice = $this->supplierService->createInvoice($data);
        return $this->responseService->success($invoice, 'Invoice created successfully', 201);
    }

    public function showInvoice(int $supplierId, int $invoiceId): JsonResponse
    {
        $invoice = $this->supplierService->findInvoice($invoiceId);
        if (!$invoice || $invoice->supplier_id !== $supplierId) {
            return $this->responseService->error('Invoice not found', 404);
        }
        return $this->responseService->success($invoice, 'Invoice retrieved successfully');
    }

    // =============================================
    // PAYMENTS
    // =============================================

    public function payments(Request $request, int $supplierId): JsonResponse
    {
        $filters  = $request->only(['branch_id', 'start_date', 'end_date']);
        $payments = $this->supplierService->getPayments($supplierId, $filters);
        return $this->responseService->success($payments, 'Payments retrieved successfully');
    }

    public function storePayment(Request $request, int $supplierId): JsonResponse
    {
        $data = $request->validate([
            'branch_id'        => 'required|exists:branches,id',
            'amount'           => 'required|numeric|min:0.01',
            'payment_method'   => 'required|in:cash,bank_transfer,cheque,online,other',
            'payment_date'     => 'required|date',
            'reference_number' => 'nullable|string|max:100',
            'notes'            => 'nullable|string',
        ]);

        $data['supplier_id'] = $supplierId;
        $data['user_id']     = auth()->id();

        $payment = $this->supplierService->recordPayment($data);
        return $this->responseService->success($payment, 'Payment recorded successfully', 201);
    }

    // =============================================
    // CREDIT NOTES
    // =============================================

    public function storeCreditNote(Request $request, int $supplierId): JsonResponse
    {
        $data = $request->validate([
            'branch_id'           => 'required|exists:branches,id',
            'supplier_invoice_id' => 'nullable|exists:supplier_invoices,id',
            'credit_note_number'  => 'nullable|string|max:100',
            'amount'              => 'required|numeric|min:0.01',
            'reason'              => 'required|in:goods_return,damaged,overcharge,discount,expiry_return,recall,other',
            'date'                => 'required|date',
            'notes'               => 'nullable|string',
        ]);

        $data['supplier_id'] = $supplierId;
        $data['user_id']     = auth()->id();

        $creditNote = $this->supplierService->createCreditNote($data);
        return $this->responseService->success($creditNote, 'Credit note created successfully', 201);
    }

    // =============================================
    // STATEMENT / LEDGER
    // =============================================

    public function statement(Request $request, int $supplierId): JsonResponse
    {
        $filters   = $request->only(['branch_id', 'start_date', 'end_date']);
        $statement = $this->supplierService->getStatement($supplierId, $filters);
        return $this->responseService->success($statement, 'Statement retrieved successfully');
    }
}
