import 'package:pocketbase/pocketbase.dart';
import '../api/pocketbase_client.dart';
import '../../models/job.dart';

class JobHistoryEntry {
  const JobHistoryEntry({
    required this.id,
    required this.action,
    required this.createdAt,
    this.step,
    this.note,
  });
  final String id;
  final JobHistoryAction action;
  final JobStep? step;
  final String? note;
  final DateTime createdAt;
}

enum JobHistoryAction {
  accepted,
  stepCompleted,
  handedToClinic,
  approved,
  revisionRequested,
  delivered,
  cancelled,
}

extension JobHistoryActionExt on JobHistoryAction {
  String get value => switch (this) {
        JobHistoryAction.accepted => 'accepted',
        JobHistoryAction.stepCompleted => 'step_completed',
        JobHistoryAction.handedToClinic => 'handed_to_clinic',
        JobHistoryAction.approved => 'approved',
        JobHistoryAction.revisionRequested => 'revision_requested',
        JobHistoryAction.delivered => 'delivered',
        JobHistoryAction.cancelled => 'cancelled',
      };
}

class JobHistoryService {
  JobHistoryService._();
  static final instance = JobHistoryService._();

  PocketBase get _pb => PocketBaseClient.instance.pb;

  String get _currentUserId => _pb.authStore.record?.id ?? '';

  Future<List<JobHistoryEntry>> listForJob(String jobId) async {
    try {
      final result = await _pb.collection('job_status_history').getList(
            filter: 'job_id = "$jobId"',
            perPage: 200,
          );
      return (result.items.map((r) {
        final j = r.toJson();
        String? str(dynamic v) {
          final s = v as String?;
          return (s == null || s.isEmpty) ? null : s;
        }

        return JobHistoryEntry(
          id: j['id'] as String,
          action: _parseAction(j['action_type'] as String? ?? ''),
          step: str(j['step']) != null ? _parseStep(j['step'] as String) : null,
          note: str(j['note']),
          createdAt: DateTime.parse(j['created'] as String),
        );
      }).toList()
        ..sort((a, b) => a.createdAt.compareTo(b.createdAt)));
    } catch (_) {
      return [];
    }
  }

  static JobHistoryAction _parseAction(String s) => switch (s) {
        'accepted' => JobHistoryAction.accepted,
        'step_completed' => JobHistoryAction.stepCompleted,
        'handed_to_clinic' => JobHistoryAction.handedToClinic,
        'approved' => JobHistoryAction.approved,
        'revision_requested' => JobHistoryAction.revisionRequested,
        'delivered' => JobHistoryAction.delivered,
        _ => JobHistoryAction.cancelled,
      };

  static JobStep _parseStep(String s) => switch (s) {
        'olcu_kontrol' => JobStep.olcuKontrol,
        'dijital_tasarim' => JobStep.dijitalTasarim,
        'model_hazirlik' => JobStep.modelHazirlik,
        'alt_yapi_prova' => JobStep.altYapiProva,
        'ust_yapi_prova' => JobStep.ustYapiProva,
        'mum_prova' => JobStep.mumProva,
        'disler_prova' => JobStep.dislerProva,
        'dayanak_prova' => JobStep.dayanakProva,
        'kron_prova' => JobStep.kronProva,
        'fotograf_onay' => JobStep.fotografOnay,
        'kalite_kontrol' => JobStep.kaliteKontrol,
        'teslim_oncesi_kontrol' => JobStep.teslimOncesiKontrol,
        'cila_bitim' => JobStep.cilaBitim,
        _ => JobStep.olcu,
      };

  Future<void> append({
    required String jobId,
    required String clinicTenantId,
    required String labTenantId,
    required JobHistoryAction action,
    JobStep? step,
    String? note,
    String? userId,
  }) async {
    try {
      await _pb.collection('job_status_history').create(body: {
        'job_id': jobId,
        'clinic_tenant_id': clinicTenantId,
        'lab_tenant_id': labTenantId,
        'completed_by': userId ?? _currentUserId,
        'action_type': action.value,
        if (step != null) 'step': step.value,
        if (note != null && note.isNotEmpty) 'note': note,
      });
    } catch (_) {
      // history failures must never block the main mutation
    }
  }
}
