<?php

declare(strict_types=1);
namespace App\Controllers;
use App\Core\Auth;use App\Core\Controller;use App\Core\Csrf;use App\Core\Response;use App\Core\Session;use App\Services\InvoiceService;use App\Services\EmailService;use App\Services\NotificationService;use InvalidArgumentException;use RuntimeException;
final class InvoiceController extends Controller
{
    public function __construct(private ?InvoiceService $service=null, private ?EmailService $email=null, private ?NotificationService $notifications=null){$this->service??=new InvoiceService();$this->email??=new EmailService();$this->notifications??=new NotificationService();}
    public function fromSessionsForm():Response
    {
        $patientId=(int)($_GET['patient_id']??0);
        $sessions=$patientId>0?$this->service->billableSessions($patientId):[]; $assessments=$patientId>0?$this->service->billableAssessments($patientId):[];
        return $this->view('invoices/from_sessions',['pageTitle'=>'Invoice Completed Sessions','pageDescription'=>'Create an invoice from completed, billable sessions that have not been invoiced.','patients'=>$this->service->formData()['patients'],'patientId'=>$patientId,'sessions'=>$sessions,'assessments'=>$assessments,'csrf'=>Csrf::token(),'error'=>Session::pull('invoice_error'),'message'=>Session::pull('invoice_message'),'form'=>Session::pull('invoice_form')??[]]);
    }

    public function fromClinicalWork():Response
    {
        Csrf::verify((string)($_POST['_csrf']??''));
        try { $id=$this->service->createFromClinicalWork($_POST,Auth::id()??0); Session::put('invoice_message','Invoice created from clinical services successfully.'); return Response::redirect('/crm/public/invoices/'.$id.'/edit'); }
        catch(InvalidArgumentException|RuntimeException $e){ Session::put('invoice_error',$e->getMessage()); Session::put('invoice_form',$_POST); return Response::redirect('/crm/public/invoices/from-sessions?patient_id='.(int)($_POST['patient_id']??0)); }
    }

    public function index():Response{$filters=['search'=>(string)($_GET['search']??''),'status'=>(string)($_GET['status']??''),'page'=>(int)($_GET['page']??1)];return $this->view('invoices/index',['pageTitle'=>'Invoices','pageDescription'=>'Create and manage patient invoices.','invoices'=>$this->service->list($filters),'filters'=>$filters,'message'=>Session::pull('invoice_message'),'error'=>Session::pull('invoice_error')]);}
    public function createForm():Response{return $this->view('invoices/form',['pageTitle'=>'New Invoice','pageDescription'=>'Create an invoice with one or more billable service items.','invoice'=>null,'csrf'=>Csrf::token(),'form'=>Session::pull('invoice_form')??[],'error'=>Session::pull('invoice_error'),'message'=>Session::pull('invoice_message'),...$this->service->formData()]);}
    public function create():Response{Csrf::verify((string)($_POST['_csrf']??''));try{$id=$this->service->create($_POST,Auth::id()??0);Session::put('invoice_message','Invoice created successfully.');return Response::redirect('/crm/public/invoices/'.$id.'/edit');}catch(InvalidArgumentException|RuntimeException $e){Session::put('invoice_error',$e->getMessage());Session::put('invoice_form',$_POST);return Response::redirect('/crm/public/invoices/create');}}
    public function editForm(int $id):Response{$invoice=$this->service->find($id);return $this->view('invoices/form',['pageTitle'=>'Edit Invoice '.$invoice['invoice_number'],'pageDescription'=>'Update invoice details before payments are recorded.','invoice'=>$invoice,'csrf'=>Csrf::token(),'form'=>Session::pull('invoice_form')??[],'error'=>Session::pull('invoice_error'),'message'=>Session::pull('invoice_message'),...$this->service->formData()]);}
    public function update(int $id):Response{Csrf::verify((string)($_POST['_csrf']??''));try{$this->service->update($id,$_POST,Auth::id()??0);Session::put('invoice_message','Invoice updated successfully.');}catch(InvalidArgumentException|RuntimeException $e){Session::put('invoice_error',$e->getMessage());Session::put('invoice_form',$_POST);}return Response::redirect('/crm/public/invoices/'.$id.'/edit');}

    public function email(int $id): Response
    {
        Csrf::verify((string)($_POST['_csrf']??''));
        try {
            $invoice=$this->service->find($id); $email=trim((string)($invoice['patient_email']??''));
            if($email==='') throw new RuntimeException('This patient has no email address. Add one in the patient profile first.');
            $this->email->sendInvoice($id,$email,$invoice['first_name'].' '.$invoice['last_name']);
            $this->notifications->create(Auth::id()??0,'Invoice emailed','Invoice '.$invoice['invoice_number'].' was sent to '.$email,'/crm/public/invoices/'.$id.'/edit','success');
            Session::put('invoice_message','Invoice emailed successfully to '.$email.'.');
        } catch(InvalidArgumentException|RuntimeException $e) { Session::put('invoice_error',$e->getMessage()); }
        return Response::redirect('/crm/public/invoices/'.$id.'/edit');
    }
    public function status(int $id):Response{Csrf::verify((string)($_POST['_csrf']??''));try{$this->service->setStatus($id,(string)($_POST['status']??''),Auth::id()??0);Session::put('invoice_message','Invoice status updated.');}catch(InvalidArgumentException|RuntimeException $e){Session::put('invoice_error',$e->getMessage());}return Response::redirect('/crm/public/invoices/'.$id.'/edit');}
}
