<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Response;
use App\Models\CreditNoteModel;
use App\Models\TenantModel;
use App\Helpers\PDFHelper;
use Exception;

class CreditNoteController extends Controller
{
    private CreditNoteModel $creditNoteModel;

    public function __construct()
    {
        $this->creditNoteModel = new CreditNoteModel();
    }

    public function index(): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $filters  = $_GET;
        $page     = (int) ($_GET['page'] ?? 1);
        $perPage  = (int) ($_GET['per_page'] ?? 50);

        $notes = $this->creditNoteModel->getAll($tenantId, $filters, $page, $perPage);
        $total = $this->creditNoteModel->countAllCN($tenantId, $filters);
        Response::success(['items' => $notes, 'total' => $total]);
    }

    public function show(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $note = $this->creditNoteModel->getById((int)$id, $tenantId);
        if (!$note) {
            Response::error('Credit Note not found', [], 404);
            return;
        }

        $tenantModel = new TenantModel();
        $note['tenant'] = array_merge($tenantModel->find($tenantId) ?? [], $tenantModel->getSettings($tenantId) ?? []);

        Response::success($note);
    }

    public function store(): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $userId   = (int) $_REQUEST['user']['sub'];
        $data     = $this->getJsonBody();

        $this->validate($data, [
            'customer_id' => 'required',
            'items'       => 'required|array'
        ]);

        try {
            $result = $this->creditNoteModel->createCN($tenantId, $data, $userId);
            Response::success($result, 'Credit Note created successfully', 201);
        } catch (Exception $e) {
            Response::error($e->getMessage(), [], 400); // DEBUG: " . $e->getFile() . ":" . $e->getLine() . "
        }
    }

    public function update(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $data     = $this->getJsonBody();

        try {
            $existing = $this->creditNoteModel->getById((int)$id, $tenantId);
            if (!$existing) Response::error('Credit Note not found', [], 404);
            if ($existing['status'] !== 'draft') {
                Response::error('Only draft Credit Notes can be edited.', [], 422);
                return;
            }
            $this->creditNoteModel->updateCN((int)$id, $tenantId, $data);
            Response::success([], 'Credit Note updated successfully');
        } catch (Exception $e) {
            Response::error($e->getMessage(), [], 400); // DEBUG: " . $e->getFile() . ":" . $e->getLine() . "
        }
    }

    public function destroy(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        try {
            $existing = $this->creditNoteModel->getById((int)$id, $tenantId);
            if (!$existing) Response::error('Credit Note not found', [], 404);
            if ($existing['status'] === 'issued') {
                Response::error('Issued Credit Notes cannot be deleted.', [], 422);
                return;
            }
            $this->creditNoteModel->deleteCN((int)$id, $tenantId);
            Response::success([], 'Credit Note deleted successfully');
        } catch (Exception $e) {
            Response::error($e->getMessage(), [], 400); // DEBUG: " . $e->getFile() . ":" . $e->getLine() . "
        }
    }

    public function finalize(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $userId   = (int) $_REQUEST['user']['sub'];
        try {
            $this->creditNoteModel->finalizeCN((int)$id, $tenantId, $userId);
            Response::success([], 'Credit Note issued and stock updated.');
        } catch (Exception $e) {
            Response::error($e->getMessage());
        }
    }

    public function pdf(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $cn = $this->creditNoteModel->getById((int)$id, $tenantId);
        if (!$cn) {
            Response::error('Credit Note not found', [], 404);
            return;
        }

        $tenantModel   = new TenantModel();
        $tenantProfile = $tenantModel->find($tenantId) ?? [];
        $tenantSettings = $tenantModel->getSettings($tenantId) ?? [];
        $businessDetails = array_merge($tenantProfile, $tenantSettings);

        PDFHelper::stream($cn, $businessDetails, $cn['template'] ?? $tenantSettings['default_template'] ?? 'classic');
    }
}
