<?php

namespace portalpeople\invoicing\controllers;

use portalpeople\invoicing\models\Invoicesbe;
use portalpeople\creditnotes\models\CreditNote;
use Yii;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;

/**
 * Invoice Controller
 *
 * Handles invoice viewing, credit note creation, and related operations.
 */
class InvoiceController extends Controller
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'actions' => ['view', 'list', 'credit-notes'],
                        'allow' => true,
                        'roles' => ['@'], // Logged in users
                    ],
                    [
                        'actions' => ['create-credit-note', 'issue-credit-note'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function ($rule, $action) {
                            // Only allow if user has admin or finance role
                            return Yii::$app->user->can('adminAccess') || Yii::$app->user->can('financeAccess');
                        }
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'issue-credit-note' => ['post'],
                ],
            ],
        ];
    }

    /**
     * List invoices for a cart
     *
     * @param int $cartId
     * @return string
     */
    public function actionList($cartId)
    {
        $cart = \backend\models\Cartsbe::findOne($cartId);
        if (!$cart) {
            throw new NotFoundHttpException('Cart not found.');
        }

        $invoices = Invoicesbe::find()
            ->where(['source_cart_id' => $cartId])
            ->all();

        return $this->render('list', [
            'cart' => $cart,
            'invoices' => $invoices,
        ]);
    }

    /**
     * View single invoice
     *
     * @param int $id
     * @return string
     */
    public function actionView($id)
    {
        $invoice = $this->findInvoice($id);
        
        $creditNotes = CreditNote::find()
            ->where(['invoice_id' => $id])
            ->all();

        return $this->render('view', [
            'invoice' => $invoice,
            'creditNotes' => $creditNotes,
        ]);
    }

    /**
     * List credit notes for invoice
     *
     * @param int $invoiceId
     * @return string
     */
    public function actionCreditNotes($invoiceId)
    {
        $invoice = $this->findInvoice($invoiceId);
        
        $creditNotes = CreditNote::find()
            ->where(['entity_id' => $invoiceId, 'entity_type' => Invoicesbe::class])
            ->orderBy(['created_at' => SORT_DESC])
            ->all();

        return $this->render('credit-notes', [
            'invoice' => $invoice,
            'creditNotes' => $creditNotes,
        ]);
    }

    /**
     * Create new credit note for invoice
     *
     * @param int $invoiceId
     * @return string|\yii\web\Response
     */
    public function actionCreateCreditNote($invoiceId)
    {
        $invoice = $this->findInvoice($invoiceId);

        if (!$invoice->canAddCreditNote()) {
            throw new \yii\web\BadRequestHttpException('Invoice balance is fully credited.');
        }

        $creditNote = new CreditNote([
            'entity_id' => $invoiceId,
            'entity_type' => Invoicesbe::class,
        ]);

        if ($creditNote->load(Yii::$app->request->post()) && $creditNote->validate()) {
            if ($creditNote->save()) {
                Yii::$app->session->setFlash('success', 'Credit note created successfully.');
                return $this->redirect(['credit-notes', 'invoiceId' => $invoiceId]);
            }
        }

        return $this->render('create-credit-note', [
            'invoice' => $invoice,
            'creditNote' => $creditNote,
        ]);
    }

    /**
     * Issue (finalize) a credit note
     *
     * @param int $creditNoteId
     * @return \yii\web\Response
     */
    public function actionIssueCreditNote($creditNoteId)
    {
        $creditNote = CreditNote::findOne($creditNoteId);
        if (!$creditNote) {
            throw new NotFoundHttpException('Credit note not found.');
        }

        if (!Yii::$app->request->validateCsrfToken()) {
            throw new \yii\web\BadRequestHttpException('Invalid CSRF token.');
        }

        if ($creditNote->issue()) {
            Yii::$app->session->setFlash('success', 'Credit note issued successfully.');
        } else {
            Yii::$app->session->setFlash('error', 'Failed to issue credit note.');
        }

        return $this->redirect(['credit-notes', 'invoiceId' => $creditNote->entity_id]);
    }

    /**
     * Find invoice by ID
     *
     * @param int $id
     * @return Invoicesbe
     * @throws NotFoundHttpException
     */
    protected function findInvoice($id)
    {
        $invoice = Invoicesbe::findOne($id);
        if (!$invoice) {
            throw new NotFoundHttpException('Invoice not found.');
        }
        return $invoice;
    }
}
