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

class ConnectionStats {
  const ConnectionStats({
    required this.totalJobs,
    required this.byStatus,
    required this.byType,
    required this.totalRevenue,
    required this.pendingRevenue,
    required this.thisMonthJobs,
    required this.lastMonthJobs,
    required this.revisionCount,
    required this.recentJobs,
  });

  final int totalJobs;
  final Map<String, int> byStatus;     // 'in_progress', 'sent', 'delivered', 'cancelled'
  final Map<String, int> byType;       // prosthetic_type -> count
  final double totalRevenue;
  final double pendingRevenue;
  final int thisMonthJobs;
  final int lastMonthJobs;
  final int revisionCount;
  final List<Job> recentJobs;

  int get deliveredJobs => byStatus['delivered'] ?? 0;
  int get activeJobs => (byStatus['in_progress'] ?? 0) + (byStatus['sent'] ?? 0);
  int get cancelledJobs => byStatus['cancelled'] ?? 0;
  double get revisionRate => totalJobs > 0 ? revisionCount / totalJobs * 100 : 0;
  double get completionRate => totalJobs > 0 ? deliveredJobs / totalJobs * 100 : 0;
}

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

  PocketBase get _pb => PocketBaseClient.instance.pb;

  Future<ConnectionStats> fetchStats({
    required String labTenantId,
    required String clinicTenantId,
  }) async {
    final now = DateTime.now();
    final thisMonthStart = DateTime(now.year, now.month, 1);
    final lastMonthStart = DateTime(now.year, now.month - 1, 1);
    final lastMonthEnd = thisMonthStart.subtract(const Duration(seconds: 1));

    final filter = 'lab_tenant_id = "$labTenantId" && clinic_tenant_id = "$clinicTenantId"';

    final results = await Future.wait([
      _pb.collection('jobs').getList(
        filter: filter,
        perPage: 500,
        expand: 'clinic_tenant_id,lab_tenant_id',
      ),
      _pb.collection('finance_entries').getList(
        filter: 'tenant_id = "$labTenantId" && job_id.clinic_tenant_id = "$clinicTenantId"',
        perPage: 500,
      ),
    ]);

    final jobsResult = results[0];
    final financeResult = results[1];

    final allJobs = jobsResult.items
        .map((r) => Job.fromJson(r.toJson()))
        .toList();

    // Status breakdown
    final byStatus = <String, int>{};
    final byType = <String, int>{};
    int thisMonthJobs = 0;
    int lastMonthJobs = 0;
    int revisionCount = 0;

    for (final job in allJobs) {
      // Status
      final s = job.status.value;
      byStatus[s] = (byStatus[s] ?? 0) + 1;

      // Type
      final t = job.prostheticType.value;
      byType[t] = (byType[t] ?? 0) + 1;

      // Monthly
      final created = job.dateCreated;
      if (created.isAfter(thisMonthStart)) thisMonthJobs++;
      else if (created.isAfter(lastMonthStart) && created.isBefore(lastMonthEnd)) lastMonthJobs++;

      // Revision
      if (job.status == JobStatus.inProgress && job.currentStep == null) revisionCount++;
    }

    // Finance
    double totalRevenue = 0;
    double pendingRevenue = 0;
    for (final r in financeResult.items) {
      final j = r.toJson();
      final amount = (j['amount'] as num?)?.toDouble() ?? 0;
      totalRevenue += amount;
      if (j['status'] == 'pending') pendingRevenue += amount;
    }

    // Recent jobs (last 5 delivered or sent)
    final recent = allJobs
        .where((j) => j.status == JobStatus.delivered || j.status == JobStatus.sent)
        .toList()
      ..sort((a, b) => b.dateCreated.compareTo(a.dateCreated));

    return ConnectionStats(
      totalJobs: allJobs.length,
      byStatus: byStatus,
      byType: byType,
      totalRevenue: totalRevenue,
      pendingRevenue: pendingRevenue,
      thisMonthJobs: thisMonthJobs,
      lastMonthJobs: lastMonthJobs,
      revisionCount: revisionCount,
      recentJobs: recent.take(5).toList(),
    );
  }
}
