<?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\AssignmentService;
use App\Services\ReportService;
use InvalidArgumentException;
use RuntimeException;

final class ReportController extends Controller
{
    public function __construct(private ?ReportService $service=null,private ?AssignmentService $assignments=null){$this->service??=new ReportService();$this->assignments??=new AssignmentService();}
    public function index():Response{$tid=$this->therapistId();$filters=['search'=>(string)($_GET['search']??''),'status'=>(string)($_GET['status']??''),'page'=>(int)($_GET['page']??1)];return $this->view('reports/index',['pageTitle'=>'Clinical Reports','pageDescription'=>'Clinical reports and approval workflow.','reports'=>$this->service->list($filters,$tid),'filters'=>$filters]);}
    public function createForm():Response{$tid=$this->therapistId();return $this->view('reports/form',['pageTitle'=>'New Clinical Report','pageDescription'=>'Create a report for a currently assigned patient.','report'=>null,'version'=>null,'versions'=>[],'csrf'=>Csrf::token(),'form'=>Session::pull('report_form')??[],'error'=>Session::pull('report_error'),'message'=>Session::pull('report_message'),...$this->service->formData($tid),'therapistLocked'=>$tid!==null]);}
    public function create():Response{Csrf::verify((string)($_POST['_csrf']??''));$tid=$this->therapistId();try{$id=$this->service->create($_POST,Auth::id()??0,$tid);Session::put('report_message','Report draft created successfully.');return Response::redirect('/crm/public/reports/'.$id.'/edit');}catch(InvalidArgumentException|RuntimeException $e){Session::put('report_error',$e->getMessage());Session::put('report_form',$_POST);return Response::redirect('/crm/public/reports/create');}}
    public function editForm(int $id):Response{$tid=$this->therapistId();$r=$this->service->find($id);$this->authorize($r,$tid);$v=$this->service->versions($id);$current=$v[0]??null;$form=$this->decode($current['content']??'');return $this->view('reports/form',['pageTitle'=>'Report '.$r['report_reference'],'pageDescription'=>'Clinical report version '.$r['current_version'].'.','report'=>$r,'version'=>$current,'versions'=>$v,'csrf'=>Csrf::token(),'form'=>Session::pull('report_form')??$form,'error'=>Session::pull('report_error'),'message'=>Session::pull('report_message'),...$this->service->formData($tid),'therapistLocked'=>$tid!==null]);}
    public function update(int $id):Response{Csrf::verify((string)($_POST['_csrf']??''));$tid=$this->therapistId();try{$r=$this->service->find($id);$this->authorize($r,$tid);$this->service->update($id,$_POST,Auth::id()??0,$tid);Session::put('report_message','Report draft saved.');}catch(InvalidArgumentException|RuntimeException $e){Session::put('report_error',$e->getMessage());Session::put('report_form',$_POST);}return Response::redirect('/crm/public/reports/'.$id.'/edit');}
    public function submit(int $id):Response{return $this->action($id,fn()=>$this->service->submit($id,Auth::id()??0,$this->therapistId()),'Report submitted for review.');}
    public function review(int $id):Response{return $this->action($id,fn()=>$this->service->review($id,Auth::id()??0),'Report moved under review.');}
    public function returnForChanges(int $id):Response{return $this->action($id,fn()=>$this->service->returnForChanges($id,Auth::id()??0),'Report returned for changes.');}
    public function approve(int $id):Response{return $this->action($id,fn()=>$this->service->approve($id,Auth::id()??0),'Report approved and locked.');}
    public function newVersion(int $id):Response{Csrf::verify((string)($_POST['_csrf']??''));try{$this->service->newVersion($id,Auth::id()??0,$this->therapistId());Session::put('report_message','New report version created.');}catch(InvalidArgumentException|RuntimeException $e){Session::put('report_error',$e->getMessage());}return Response::redirect('/crm/public/reports/'.$id.'/edit');}
    private function action(int $id,callable $fn,string $message):Response{Csrf::verify((string)($_POST['_csrf']??''));try{$fn();Session::put('report_message',$message);}catch(InvalidArgumentException|RuntimeException $e){Session::put('report_error',$e->getMessage());}return Response::redirect('/crm/public/reports/'.$id.'/edit');}
    private function therapistId():?int{if(!Auth::hasRole('THERAPIST'))return null;$id=$this->assignments->therapistIdForUser(Auth::id()??0);if($id===null)throw new RuntimeException('Your therapist profile is not active.',403);return $id;}
    private function authorize(array $r,?int $tid):void{if($tid!==null&&!$this->service->canTherapistAccess($r,$tid))throw new RuntimeException('You do not have permission to access this report.',403);}
    private function decode(string $content):array{$d=json_decode($content,true);return is_array($d)?$d:[];}
}
