<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Auth;
use App\Core\Csrf;
use App\Core\DB;
use App\Core\Request;
use App\Core\Response;
use App\Repositories\PurchaseInvoiceRepository;
use App\Services\PurchaseInvoiceService;
use Throwable;
use App\Modules\Purchases\Application\Services\PurchasesRouteContext;

final class PurchaseInvoiceController
{
    private \PDO $pdo;
    private PurchaseInvoiceRepository $repo;
    private PurchaseInvoiceService $service;
    private PurchasesRouteContext $routeContext;

    public function __construct()
    {
        $this->pdo = DB::pdo();
        $this->repo = new PurchaseInvoiceRepository($this->pdo);
        $this->service = new PurchaseInvoiceService($this->pdo, $this->repo);
        $this->routeContext = new PurchasesRouteContext();
    }

    private function ensureSchemaView(): bool
    {
        try {
            $this->service->ensureSchemaOrThrow();
            return true;
        } catch (Throwable $e) {
            Response::view('pages/dashboard', ['error' => $e->getMessage()]);
            return false;
        }
    }

    public function index(): void
    {
        Auth::requireLogin();
        require_permission('purchases.view');
        if (!$this->ensureSchemaView()) return;

        $forReturn = ((string)Request::get('for_return', '') === '1');
        $q = trim((string)Request::get('q', ''));
        $status = trim((string)Request::get('status', ''));
        $from = trim((string)Request::get('from', ''));
        $to = trim((string)Request::get('to', ''));
        $page = max(1, (int) Request::get('page', 1));
        $perPage = 25;
        $totalRows = $this->repo->countSearch($q, $status, $from, $to, $forReturn);
        $totalPages = max(1, (int) ceil($totalRows / $perPage));
        if ($page > $totalPages) { $page = $totalPages; }
        $offset = ($page - 1) * $perPage;
        $rows = $this->repo->searchPage($q, $status, $from, $to, $forReturn, $offset, $perPage);
        Response::view('pages/purchases/invoices_index', [
            'purchase_invoices_url' => $this->routeContext->invoicesPath(),
            'purchase_invoice_form_url' => $this->routeContext->invoiceFormPath(),
            'purchase_invoice_view_base_url' => $this->routeContext->invoiceViewPath(),
            'purchase_returns_url' => $this->routeContext->returnsPath(),
            'purchase_return_form_base_url' => $this->routeContext->returnFormPath(),
            'rows' => $rows,
            'page' => $page,
            'per_page' => $perPage,
            'total_pages' => $totalPages,
            'total_rows' => $totalRows,
            'from_row' => $totalRows > 0 ? ($offset + 1) : 0,
            'to_row' => min($totalRows, $offset + count($rows)),
            'q' => $q,
            'status' => strtoupper($status),
            'from' => $from,
            'to' => $to,
            'for_return' => $forReturn,
            'page_title' => 'فواتير الشراء',
            'breadcrumbs' => [
                $this->routeContext->dashboardCrumb(),
                ['label'=>'المشتريات','url'=>$this->routeContext->purchasesBoardPath()],
                ['label'=>'فواتير الشراء'],
            ],
        ]);
    }

    public function form(): void
    {
        Auth::requireLogin();
        if (!$this->ensureSchemaView()) return;
        $id = (int)Request::get('id', 0);
        require_permission($id > 0 ? 'purchases.edit' : 'purchases.create');
        try {
            if (Request::isPost()) {
                Csrf::verify();
                $savedId = $this->service->save($id, Request::all(), (int)(current_user_id() ?: 0));
                Response::flash('success', ((string)Request::post('save_action', 'draft') === 'post') ? 'تم حفظ وترحيل فاتورة الشراء.' : 'تم حفظ الفاتورة كمسودة.');
                Response::redirect($this->routeContext->invoiceViewPath($savedId));
                return;
            }
            $data = $this->service->loadForm($id);
            Response::view('pages/purchases/invoice_form', $data + [
                'purchase_invoices_url' => $this->routeContext->invoicesPath(),
                'purchase_invoice_view_url' => $this->routeContext->invoiceViewPath($id),
                'page_title' => $id > 0 ? 'تعديل فاتورة شراء' : 'إنشاء فاتورة شراء',
                'breadcrumbs' => [
                    $this->routeContext->dashboardCrumb(),
                    ['label'=>'فواتير الشراء','url'=>$this->routeContext->invoicesPath()],
                    ['label'=> $id > 0 ? 'تعديل' : 'إنشاء'],
                ],
            ]);
        } catch (Throwable $e) {
            $msg = $e->getMessage();
            if ($msg === 'Not found') { http_response_code(404); exit('Not found'); }
            Response::flash('danger', 'تعذر حفظ الفاتورة: ' . $msg);
            Response::redirect($this->routeContext->invoiceFormPath($id));
        }
    }

    public function view(): void
    {
        Auth::requireLogin();
        require_permission('purchases.view');
        if (!$this->ensureSchemaView()) return;
        $id = (int)Request::get('id', 0);
        if ($id <= 0) { http_response_code(400); exit('Invalid'); }

        if (Request::isPost()) {
            Csrf::verify();
            $action = (string)Request::post('action', '');
            try {
                if ($action === 'post') {
                    $this->service->postExistingDraft($id, (int)(current_user_id() ?: 0));
                    Response::flash('success', 'تم ترحيل فاتورة الشراء.');
                } elseif ($action === 'cancel') {
                    require_permission('purchases.edit');
                    $this->service->cancelDraft($id);
                    Response::flash('success', 'تم إلغاء الفاتورة (مسودة).');
                }
            } catch (Throwable $e) {
                Response::flash('danger', (($action === 'post') ? 'تعذر الترحيل: ' : 'تعذر الإلغاء: ') . $e->getMessage());
            }
            Response::redirect($this->routeContext->invoiceViewPath($id));
            return;
        }

        $invoice = $this->repo->findViewById($id);
        if (!$invoice) { http_response_code(404); exit('Not found'); }
        $ret = $this->repo->fetchRetSummary($id);
        $paidSum = $this->repo->fetchPaidSum($id, (float)($invoice['paid_amount'] ?? 0));
        $netTotal = (float)($invoice['total'] ?? 0) - (float)$ret['sum'];
        $dueAmount = max(0, $netTotal - $paidSum);

        Response::view('pages/purchases/invoice_view', [
            'purchase_invoices_url' => $this->routeContext->invoicesPath(),
            'purchase_invoice_form_url' => $this->routeContext->invoiceFormPath(),
            'purchase_returns_url' => $this->routeContext->returnsPath(),
            'purchase_return_form_url' => $this->routeContext->returnFormPath(),
            'invoice' => $invoice,
            'lines' => $this->repo->fetchLines($id),
            'retCount' => $ret['count'],
            'retSum' => $ret['sum'],
            'paidSum' => $paidSum,
            'dueAmount' => $dueAmount,
            'page_title' => 'عرض فاتورة شراء',
            'breadcrumbs' => [
                $this->routeContext->dashboardCrumb(),
                ['label'=>'فواتير الشراء','url'=>$this->routeContext->invoicesPath()],
                ['label'=>'عرض'],
            ],
        ]);
    }
}
