<?php
declare(strict_types=1);

namespace App\Modules\Procurement\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Procurement\Models\VendorPayment;
use App\Modules\Procurement\Services\VendorPaymentService;
use App\Modules\Inventory\Models\Supplier;

class VendorPaymentController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'status'      => trim((string) $request->get('status', '')),
            'supplier_id' => trim((string) $request->get('supplier_id', '')),
            'date_from'   => trim((string) $request->get('date_from', '')),
            'date_to'     => trim((string) $request->get('date_to', '')),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = VendorPayment::search($filters, 25, $page);

        return $this->view('Procurement.Views.payments.index', [
            'payments'   => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
            'suppliers'  => Supplier::allActive(),
            'statuses'   => VendorPayment::getStatuses(),
        ]);
    }

    public function create(Request $request): Response
    {
        $db = App::getInstance()->db();

        $approvedInvoices = $db->select(
            "SELECT vi.*, s.`name_ar` as supplier_name
             FROM `vendor_invoices` vi
             JOIN `suppliers` s ON s.`id` = vi.`supplier_id`
             WHERE vi.`status` IN ('approved', 'partial_paid')
             ORDER BY vi.`due_date` ASC"
        );

        $bankAccounts = $db->select("SELECT * FROM `bank_accounts` WHERE `is_active` = 1 ORDER BY `name_ar`");

        return $this->view('Procurement.Views.payments.form', [
            'suppliers'        => Supplier::allActive(),
            'approvedInvoices' => $approvedInvoices,
            'bankAccounts'     => $bankAccounts,
            'paymentMethods'   => VendorPayment::getPaymentMethods(),
        ]);
    }

    public function store(Request $request): Response
    {
        $data = [
            'supplier_id'      => (int) $request->post('supplier_id', 0),
            'invoice_id'       => (int) $request->post('invoice_id', 0) ?: null,
            'amount'           => trim((string) $request->post('amount', '0')),
            'payment_method'   => trim((string) $request->post('payment_method', 'bank_transfer')),
            'bank_account_id'  => (int) $request->post('bank_account_id', 0) ?: null,
            'check_number'     => trim((string) $request->post('check_number', '')) ?: null,
            'reference_number' => trim((string) $request->post('reference_number', '')) ?: null,
            'payment_date'     => trim((string) $request->post('payment_date', '')) ?: date('Y-m-d'),
            'notes'            => trim((string) $request->post('notes', '')) ?: null,
        ];

        try {
            $paymentId = VendorPaymentService::createPayment($data);
            return $this->redirect('/procurement/payments/' . $paymentId)->withSuccess('تم إنشاء الدفعة بنجاح');
        } catch (\RuntimeException $e) {
            return $this->redirect('/procurement/payments/create')->withError($e->getMessage());
        }
    }

    public function show(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $payment = $db->selectOne(
            "SELECT vp.*, s.`name_ar` as supplier_name, vi.`internal_number` as invoice_internal,
                    vi.`invoice_number` as invoice_supplier_number,
                    ea.`full_name_ar` as approver_name,
                    ec.`full_name_ar` as completer_name,
                    ev.`full_name_ar` as voider_name
             FROM `vendor_payments` vp
             JOIN `suppliers` s ON s.`id` = vp.`supplier_id`
             LEFT JOIN `vendor_invoices` vi ON vi.`id` = vp.`invoice_id`
             LEFT JOIN `employees` ea ON ea.`id` = vp.`approved_by`
             LEFT JOIN `employees` ec ON ec.`id` = vp.`completed_by`
             LEFT JOIN `employees` ev ON ev.`id` = vp.`voided_by`
             WHERE vp.`id` = ?",
            [(int) $id]
        );

        if (!$payment) {
            return $this->redirect('/procurement/payments')->withError('الدفعة غير موجودة');
        }

        return $this->view('Procurement.Views.payments.show', [
            'payment' => $payment,
        ]);
    }

    public function approve(Request $request, string $id): Response
    {
        try {
            VendorPaymentService::approvePayment((int) $id);
            return $this->redirect('/procurement/payments/' . $id)->withSuccess('تم اعتماد الدفعة');
        } catch (\RuntimeException $e) {
            return $this->redirect('/procurement/payments/' . $id)->withError($e->getMessage());
        }
    }

    public function complete(Request $request, string $id): Response
    {
        try {
            VendorPaymentService::completePayment((int) $id);
            return $this->redirect('/procurement/payments/' . $id)->withSuccess('تم إتمام الدفعة — سيتم تسجيل القيد المحاسبي');
        } catch (\RuntimeException $e) {
            return $this->redirect('/procurement/payments/' . $id)->withError($e->getMessage());
        }
    }

    public function void(Request $request, string $id): Response
    {
        $reason = trim((string) $request->post('void_reason', ''));
        if (empty($reason)) {
            return $this->redirect('/procurement/payments/' . $id)->withError('يجب إدخال سبب الإلغاء');
        }

        try {
            VendorPaymentService::voidPayment((int) $id, $reason);
            return $this->redirect('/procurement/payments/' . $id)->withSuccess('تم إلغاء الدفعة');
        } catch (\RuntimeException $e) {
            return $this->redirect('/procurement/payments/' . $id)->withError($e->getMessage());
        }
    }
}
