import 'dart:async'; import 'package:pocketbase/pocketbase.dart'; import '../../../core/api/pocketbase_client.dart'; import '../../../core/services/job_history_service.dart'; import '../../../models/job.dart'; const _listExpand = 'clinic_tenant_id,lab_tenant_id'; const _detailExpand = 'clinic_tenant_id,lab_tenant_id,patient_id,prosthetic_id'; class ClinicJobsRepository { ClinicJobsRepository._(); static final instance = ClinicJobsRepository._(); PocketBase get _pb => PocketBaseClient.instance.pb; Future> listOutbound( String clinicTenantId, { List? statuses, String? location, String? filterExtra, int page = 1, int limit = 30, }) async { final filterParts = ['clinic_tenant_id = "$clinicTenantId"']; if (statuses != null && statuses.isNotEmpty) { final statusFilter = statuses.map((s) => 'status = "$s"').join(' || '); filterParts.add('($statusFilter)'); } if (location != null) { filterParts.add('location = "$location"'); } if (filterExtra != null) { filterParts.add('($filterExtra)'); } final result = await _pb.collection('jobs').getList( page: page, perPage: limit, filter: filterParts.join(' && '), expand: _listExpand, ); return (result.items.map((r) => Job.fromJson(r.toJson())).toList() ..sort((a, b) => b.dateCreated.compareTo(a.dateCreated))); } Future getJob(String jobId) async { final record = await _pb.collection('jobs').getOne(jobId, expand: _detailExpand); return Job.fromJson(record.toJson()); } Future createJob({ required String clinicTenantId, required String labTenantId, required String patientCode, required String prostheticId, required ProstheticType prostheticType, required List teeth, String? patientId, String? color, String? description, String? dueDate, bool provaRequired = true, }) async { final record = await _pb.collection('jobs').create(body: { 'clinic_tenant_id': clinicTenantId, 'lab_tenant_id': labTenantId, 'patient_code': patientCode, if (patientId != null) 'patient_id': patientId, 'prosthetic_id': prostheticId, 'prosthetic_type': prostheticType.value, 'member_count': teeth.length, 'teeth': teeth, if (color != null) 'color': color, if (description != null) 'description': description, if (dueDate != null) 'due_date': dueDate, 'status': 'pending', 'location': 'at_clinic', 'prova_required': provaRequired, }); return Job.fromJson(record.toJson()); } Future approveAtClinic(String jobId, Job job, {String? note}) async { final nextStep = job.nextStep; if (nextStep == null) throw Exception('Bu aşamadan ileri gidilemez.'); final record = await _pb.collection('jobs').update(jobId, body: { 'current_step': nextStep.value, 'location': 'at_lab', }); final updated = Job.fromJson(record.toJson()); unawaited(JobHistoryService.instance.append( jobId: jobId, clinicTenantId: job.clinicTenantId, labTenantId: job.labTenantId, action: JobHistoryAction.approved, step: job.currentStep, note: note, )); return updated; } Future requestRevision(String jobId, Job job, {required String note}) async { final record = await _pb.collection('jobs').update(jobId, body: { 'location': 'at_lab', }); final updated = Job.fromJson(record.toJson()); unawaited(JobHistoryService.instance.append( jobId: jobId, clinicTenantId: job.clinicTenantId, labTenantId: job.labTenantId, action: JobHistoryAction.revisionRequested, step: job.currentStep, note: note, )); return updated; } Future markDelivered(String jobId, Job job, {String? note}) async { final record = await _pb.collection('jobs').update(jobId, body: { 'status': 'delivered', }); unawaited(JobHistoryService.instance.append( jobId: jobId, clinicTenantId: job.clinicTenantId, labTenantId: job.labTenantId, action: JobHistoryAction.delivered, note: note, )); return Job.fromJson(record.toJson()); } Future cancelJob(String jobId, Job job) async { final record = await _pb.collection('jobs').update(jobId, body: { 'status': 'cancelled', }); unawaited(JobHistoryService.instance.append( jobId: jobId, clinicTenantId: job.clinicTenantId, labTenantId: job.labTenantId, action: JobHistoryAction.cancelled, )); return Job.fromJson(record.toJson()); } Future>> listApprovedLabs(String clinicTenantId) async { final result = await _pb.collection('connections').getList( filter: 'clinic_tenant_id = "$clinicTenantId" && status = "approved"', expand: 'lab_tenant_id', perPage: 100, ); return result.items.map((r) { final expand = r.toJson()['expand'] as Map?; return expand?['lab_tenant_id'] as Map? ?? {'id': r.data['lab_tenant_id']}; }).toList(); } Future> listJobsByPatient(String patientId, {int limit = 50}) async { final result = await _pb.collection('jobs').getList( filter: 'patient_id = "$patientId"', perPage: limit, expand: _listExpand, ); return (result.items.map((r) => Job.fromJson(r.toJson())).toList() ..sort((a, b) => b.dateCreated.compareTo(a.dateCreated))); } Future countDelivered(String clinicTenantId, {DateTime? from, DateTime? to}) async { final parts = ['clinic_tenant_id = "$clinicTenantId"', 'status = "delivered"']; if (from != null) parts.add('updated >= "${_date(from)}"'); if (to != null) parts.add('updated < "${_date(to)}"'); final r = await _pb.collection('jobs').getList(perPage: 1, filter: parts.join(' && ')); return r.totalItems; } static String _date(DateTime d) => d.toIso8601String().split('T').first; }