<?php

namespace App\Controllers\Api;

use App\Controllers\BaseController;
use App\Models\CareRequestModel;
use App\Models\UserModel;
use App\Services\ApiTokenService;
use App\Services\DispatchService;
use App\Services\PaymentService;

class MobileApi extends BaseController
{
    public function login()
    {
        $data=$this->request->getJSON(true) ?: $this->request->getPost();$email=strtolower(trim((string)($data['email']??'')));$password=(string)($data['password']??'');$user=(new UserModel())->where('email',$email)->first();
        if(!$user || $user['status']!=='active' || !password_verify($password,$user['password_hash']))return $this->response->setStatusCode(401)->setJSON(['error'=>'Invalid credentials']);
        $token=(new ApiTokenService())->issue((int)$user['id'],'mobile');
        return $this->response->setJSON(['token'=>$token,'token_type'=>'Bearer','expires_in'=>2592000,'user'=>['id'=>(int)$user['id'],'name'=>$user['full_name'],'email'=>$user['email'],'role'=>$user['role']]]);
    }
    public function me(){ $u=auth_user();unset($u['token_id']);return $this->response->setJSON(['data'=>$u]); }
    public function logout(){ $u=auth_user();if(isset($u['token_id']))(new ApiTokenService())->revoke((int)$u['token_id']);return $this->response->setJSON(['ok'=>true]); }
    public function createPatientRequest()
    {
        $u=auth_user();if(($u['role']??'')!=='patient')return $this->response->setStatusCode(403)->setJSON(['error'=>'Patient role required']);$data=$this->request->getJSON(true) ?: [];
        foreach(['service_id','address_text','chief_complaint'] as $key)if(empty($data[$key]))return $this->response->setStatusCode(422)->setJSON(['error'=>$key.' is required']);
        $db=db_connect();$patient=$db->table('patient_profiles')->select('id')->where('user_id',$u['id'])->get()->getRowArray();if(!$patient)return $this->response->setStatusCode(409)->setJSON(['error'=>'Patient profile is missing']);$service=$db->table('services')->where(['id'=>(int)$data['service_id'],'is_active'=>1])->get()->getRowArray();if(!$service)return $this->response->setStatusCode(422)->setJSON(['error'=>'Invalid service']);
        $id=(new CareRequestModel())->insert(['patient_id'=>$patient['id'],'family_member_id'=>$data['family_member_id']??null,'service_id'=>$service['id'],'scheduled_for'=>$data['scheduled_for']??date('Y-m-d H:i:s'),'urgency'=>in_array($data['urgency']??'routine',['routine','priority'],true)?($data['urgency']??'routine'):'routine','status'=>'matching','chief_complaint'=>substr(trim((string)$data['chief_complaint']),0,1500),'latitude'=>$data['latitude']??null,'longitude'=>$data['longitude']??null,'address_text'=>substr(trim((string)$data['address_text']),0,255),'estimated_amount'=>$service['base_price']]);
        (new PaymentService())->initiate((int)$u['id'],(int)$id,(float)$service['base_price'],'pending');$match=(new DispatchService())->assignBest((int)$id);
        return $this->response->setStatusCode(201)->setJSON(['data'=>['id'=>(int)$id,'status'=>'matching','matched'=>(bool)$match]]);
    }
    public function patientRequestStatus(int $id)
    {
        $u=auth_user();if(($u['role']??'')!=='patient')return $this->response->setStatusCode(403)->setJSON(['error'=>'Patient role required']);$db=db_connect();$patient=$db->table('patient_profiles')->select('id')->where('user_id',$u['id'])->get()->getRowArray();$row=$patient?$db->table('care_requests')->select('id,status,scheduled_for,address_text,estimated_amount,assigned_practitioner_id,accepted_at,completed_at,updated_at')->where(['id'=>$id,'patient_id'=>$patient['id']])->get()->getRowArray():null;if(!$row)return $this->response->setStatusCode(404)->setJSON(['error'=>'Request not found']);return $this->response->setJSON(['data'=>$row]);
    }

    public function practitionerOffers()
    {
        $u=auth_user();if(($u['role']??'')!=='practitioner')return $this->response->setStatusCode(403)->setJSON(['error'=>'Practitioner role required']);$db=db_connect();$p=$db->table('practitioner_profiles')->select('id')->where('user_id',$u['id'])->get()->getRowArray();if(!$p)return $this->response->setJSON(['data'=>[]]);$rows=$db->table('care_request_assignments a')->select('a.id,a.care_request_id,a.status,a.offered_at,a.expires_at,cr.address_text,cr.chief_complaint,cr.urgency,s.name service_name')->join('care_requests cr','cr.id=a.care_request_id')->join('services s','s.id=cr.service_id')->where(['a.practitioner_id'=>$p['id'],'a.status'=>'offered'])->orderBy('a.offered_at','DESC')->get()->getResultArray();return $this->response->setJSON(['data'=>$rows]);
    }

    public function practitionerRespond(int $assignmentId,string $decision)
    {
        $u=auth_user();if(($u['role']??'')!=='practitioner')return $this->response->setStatusCode(403)->setJSON(['error'=>'Practitioner role required']);if(!in_array($decision,['accept','decline'],true))return $this->response->setStatusCode(422)->setJSON(['error'=>'Invalid decision']);$db=db_connect();$p=$db->table('practitioner_profiles')->select('id')->where('user_id',$u['id'])->get()->getRowArray();$a=$p?$db->table('care_request_assignments')->where(['id'=>$assignmentId,'practitioner_id'=>$p['id'],'status'=>'offered'])->get()->getRowArray():null;if(!$a)return $this->response->setStatusCode(409)->setJSON(['error'=>'Offer is no longer available']);
        $db->transStart();if($decision==='decline'){$db->table('care_request_assignments')->where('id',$assignmentId)->update(['status'=>'declined','responded_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')]);}else{$db->table('care_request_assignments')->where('id',$assignmentId)->update(['status'=>'accepted','responded_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')]);$db->table('care_requests')->where('id',$a['care_request_id'])->whereIn('status',['matching','offered','requested'])->update(['status'=>'accepted','assigned_practitioner_id'=>$p['id'],'accepted_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')]);$cr=$db->table('care_requests')->where('id',$a['care_request_id'])->get()->getRowArray();if($cr && !$db->table('visits')->where('care_request_id',$a['care_request_id'])->countAllResults())$db->table('visits')->insert(['care_request_id'=>$a['care_request_id'],'patient_id'=>$cr['patient_id'],'practitioner_id'=>$p['id'],'status'=>'scheduled','created_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')]);}$db->transComplete();return $this->response->setJSON(['data'=>['assignment_id'=>$assignmentId,'decision'=>$decision]]);
    }

}
