<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Response;
use App\Models\DebitNoteModel;
use Exception;

class DebitNoteController extends Controller
{
    private DebitNoteModel $debitNoteModel;

    public function __construct()
    {
        $this->debitNoteModel = new DebitNoteModel();
    }

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

        $notes = $this->debitNoteModel->getAll($tenantId, $filters, $page, $perPage);
        Response::success($notes);
    }

    public function show(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $note = $this->debitNoteModel->getById((int)$id, $tenantId);

        if (!$note) {
            Response::error('Debit Note not found', [], 404);
            return;
        }

        $tenantModel = new \App\Models\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, [
            'vendor_id' => 'required',
            'grand_total' => 'required|numeric'
        ]);

        try {
            $result = $this->debitNoteModel->createDN($tenantId, $data, $userId);
            Response::success($result, 'Debit Note created successfully', 201);
        } catch (Exception $e) {
            Response::error($e->getMessage());
        }
    }

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

        try {
            $existing = $this->debitNoteModel->getById((int)$id, $tenantId);
            if (!$existing) Response::error('Debit Note not found', [], 404);
            if ($existing['status'] !== 'draft') {
                Response::error('Only draft Debit Notes can be edited.', [], 422);
            }
            $this->debitNoteModel->updateDN((int)$id, $tenantId, $data);
            Response::success([], 'Debit Note updated successfully');
        } catch (Exception $e) {
            Response::error($e->getMessage());
        }
    }

    public function destroy(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        try {
            $existing = $this->debitNoteModel->getById((int)$id, $tenantId);
            if (!$existing) Response::error('Debit Note not found', [], 404);
            if ($existing['status'] === 'issued') {
                Response::error('Issued Debit Notes cannot be deleted.', [], 422);
            }
            $this->debitNoteModel->deleteDN((int)$id, $tenantId);
            Response::success([], 'Debit Note deleted successfully');
        } catch (Exception $e) {
            Response::error($e->getMessage());
        }
    }

    public function finalize(string $id): void
    {
        $tenantId = (int) $_REQUEST['tenant_id'];
        $userId = (int) $_REQUEST['user']['sub'];
        try {
            $this->debitNoteModel->finalizeDN((int)$id, $tenantId, $userId);
            Response::success([], 'Debit Note finalized.');
        } catch (Exception $e) {
            Response::error($e->getMessage());
        }
    }

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

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

        \App\Helpers\PDFHelper::stream($dn, $businessDetails, $dn['template'] ?? $tenantSettings['default_template'] ?? 'classic');
    }
}
