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

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

  PocketBase get _pb => PocketBaseClient.instance.pb;

  Future<String> build(TenantMembership membership) async {
    final tenant = membership.tenant;
    final tenantId = tenant.id;
    final isLab = tenant.kind == TenantKind.lab;

    final now = DateTime.now();
    final dateStr = '${now.day}.${now.month}.${now.year}';

    final results = await Future.wait([
      _fetchActiveJobs(tenantId, isLab),
      _fetchRecentDelivered(tenantId, isLab),
      _fetchFinance(tenantId, isLab),
      _fetchTeam(tenantId),
    ]);

    final actions = _actionsPrompt(isLab);

    return 'Sen DLS (Dental Lab System) uygulamasinin akilli asistanisin.\n'
        '${tenant.companyName} adli ${isLab ? 'dental laboratuvarinin' : 'dis kliniginin'} verilerine erisebilirsin.\n'
        'Kullanici rolu: ${isLab ? 'LABORATUVAR' : 'KLINIK'}\n'
        '\n'
        'Tarih: $dateStr\n'
        '\n'
        '${results[0]}\n'
        '\n'
        '${results[1]}\n'
        '\n'
        '${results[2]}\n'
        '\n'
        '${results[3]}\n'
        '\n'
        '$actions\n'
        '\n'
        'Yanit kurallari:\n'
        '- Turkce, kisa ve net yaz\n'
        '- Sadece yukaridaki verilerden hareketle yorum yap\n'
        '- Listelerde madde isareti (- ) kullan\n'
        '- Onemli bilgileri **kalin** yaz\n'
        '- Aksiyon etiketlerini HERZAMAN metnin sonuna koy\n'
        '- ${isLab ? 'Is kodlari icin [ID:...] formatini kullan' : 'Hasta kodlari ve is durumlarini net belirt'}\n';
  }

  static String _actionsPrompt(bool isLab) {
    final buf = StringBuffer();
    buf.writeln('## EYLEM YETKILERIN');
    buf.writeln('Kullanici bir islem yapmak istediginde asagidaki XML etiketlerini yanita ekle:');
    buf.writeln('');
    buf.writeln('Is dosyalarini gostermek:');
    buf.writeln('<dls-action type="job_files" job_id="JOB_ID" label="AB001 dosyalarini goster"/>');
    buf.writeln('');
    buf.writeln('Is iptal etmek:');
    buf.writeln('<dls-action type="cancel_job" job_id="JOB_ID" label="AB001 isini iptal et"/>');
    if (!isLab) {
      buf.writeln('');
      buf.writeln('Teslim edildi isaretlemek (sadece klinik):');
      buf.writeln('<dls-action type="mark_delivered" job_id="JOB_ID" label="AB001 teslim edildi"/>');
    }
    buf.writeln('');
    buf.writeln('Ekip uyesi eklemek (TUM bilgiler alindiktan sonra):');
    buf.writeln('<dls-action type="add_member" email="..." first_name="..." last_name="..." role="technician|admin|doctor|delivery|finance|member" password="..." label="Ad Soyad ekle"/>');
    buf.writeln('');
    buf.writeln('KURALLAR:');
    buf.writeln('- Etiketi SADECE kullanici acikca islem istediginde ekle');
    buf.writeln('- Sifre sorulursa kullanicidan al, ASLA uydurma');
    buf.writeln('- iptal gibi geri alinmaz islemleri acikca belirt');
    buf.writeln('- Etiket icindeki job_id degerini yukaridaki is listesinden al');
    buf.writeln('- <dls-action> etiketlerini KESINLİKLE kod blogu (```xml veya ```) icine ALMA, duz metin olarak yaz');
    return buf.toString();
  }

  Future<String> _fetchActiveJobs(String tenantId, bool isLab) async {
    try {
      final tenantField = isLab ? 'lab_tenant_id' : 'clinic_tenant_id';
      final counterpartField = isLab ? 'clinic_tenant_id' : 'lab_tenant_id';
      final result = await _pb.collection('jobs').getList(
        filter: '$tenantField = "$tenantId" && status != "delivered" && status != "cancelled"',
        perPage: 60,
        sort: '-created',
        expand: counterpartField,
      );

      if (result.items.isEmpty) return '## Aktif Isler\nSu an aktif is yok.';

      final counterpartLabel = isLab ? 'Klinik' : 'Lab';
      final lines = result.items.map((r) {
        final j = r.toJson();
        final jobId = j['id'] as String? ?? '';
        final expand = j['expand'] as Map<String, dynamic>?;
        final counterpart =
            (expand?[counterpartField] as Map?)?['company_name'] as String? ?? '-';
        final status = _statusTr(j['status'] as String? ?? '');
        final prosthetic = j['prosthetic_type'] as String? ?? '-';
        final patient = j['patient_code'] as String? ?? '-';
        final step = j['current_step'] as String?;
        final stepPart = (step != null && step.isNotEmpty) ? ' | Adim: $step' : '';
        final due = j['due_date'] as String? ?? '';
        final duePart = due.isNotEmpty ? ' | Termin: ${due.substring(0, 10)}' : '';
        return '- [ID:$jobId] Hasta: $patient | $prosthetic | $status$stepPart | $counterpartLabel: $counterpart$duePart';
      }).join('\n');

      return '## Aktif Isler (${result.items.length})\n$lines';
    } catch (e) {
      return '## Aktif Isler\n(Veri alinamadi: $e)';
    }
  }

  Future<String> _fetchRecentDelivered(String tenantId, bool isLab) async {
    try {
      final tenantField = isLab ? 'lab_tenant_id' : 'clinic_tenant_id';
      final counterpartField = isLab ? 'clinic_tenant_id' : 'lab_tenant_id';
      final result = await _pb.collection('jobs').getList(
        filter: '$tenantField = "$tenantId" && status = "delivered"',
        perPage: 10,
        sort: '-updated',
        expand: counterpartField,
      );

      if (result.items.isEmpty) return '## Son Teslim Edilenler\nHenuz teslim edilen is yok.';

      final counterpartLabel = isLab ? 'Klinik' : 'Lab';
      final lines = result.items.map((r) {
        final j = r.toJson();
        final jobId = j['id'] as String? ?? '';
        final expand = j['expand'] as Map<String, dynamic>?;
        final counterpart =
            (expand?[counterpartField] as Map?)?['company_name'] as String? ?? '-';
        final prosthetic = j['prosthetic_type'] as String? ?? '-';
        final patient = j['patient_code'] as String? ?? '-';
        final updated = (j['updated'] as String? ?? '');
        final datePart = updated.length >= 10 ? updated.substring(0, 10) : '';
        return '- [ID:$jobId] Hasta: $patient | $prosthetic | $counterpartLabel: $counterpart${datePart.isNotEmpty ? ' | Tarih: $datePart' : ''}';
      }).join('\n');

      return '## Son Teslim Edilenler (son 10)\n$lines';
    } catch (_) {
      return '## Son Teslim Edilenler\n(Veri alinamadi)';
    }
  }

  Future<String> _fetchFinance(String tenantId, bool isLab) async {
    try {
      final type = isLab ? 'receivable' : 'payable';
      final result = await _pb.collection('finance_entries').getList(
        filter: 'tenant_id = "$tenantId" && type = "$type"',
        perPage: 200,
      );

      double pending = 0, paid = 0;
      for (final r in result.items) {
        final j = r.toJson();
        final amount = (j['amount'] as num?)?.toDouble() ?? 0;
        if (j['status'] == 'pending') {
          pending += amount;
        } else {
          paid += amount;
        }
      }

      final label = isLab ? 'alacak' : 'borc';
      return '## Finans\n'
          '- Bekleyen $label: ${pending.toStringAsFixed(0)} TL\n'
          '- Tahsil edilen: ${paid.toStringAsFixed(0)} TL';
    } catch (_) {
      return '## Finans\n(Veri alinamadi)';
    }
  }

  Future<String> _fetchTeam(String tenantId) async {
    try {
      final result = await _pb.collection('tenant_members').getList(
        filter: 'tenant_id = "$tenantId"',
        expand: 'user_id',
        perPage: 50,
      );

      if (result.items.isEmpty) return '## Ekip\nUye yok.';

      final lines = result.items.map((r) {
        final j = r.toJson();
        final expand = j['expand'] as Map<String, dynamic>?;
        final user = expand?['user_id'] as Map<String, dynamic>?;
        final first = (user?['first_name'] as String?) ?? '';
        final last = (user?['last_name'] as String?) ?? '';
        final email = (user?['email'] as String?) ?? '';
        final name =
            '$first $last'.trim().isNotEmpty ? '$first $last'.trim() : email;
        final role = _roleTr(j['role'] as String? ?? '');
        return '- $name ($role)';
      }).join('\n');

      return '## Ekip (${result.items.length} uye)\n$lines';
    } catch (_) {
      return '## Ekip\n(Veri alinamadi)';
    }
  }

  static String _statusTr(String s) => switch (s) {
        'pending' => 'Bekliyor',
        'in_progress' => 'Devam ediyor',
        'sent' => 'Gonderildi',
        'revision' => 'Revizyon',
        'delivered' => 'Teslim edildi',
        'cancelled' => 'Iptal',
        _ => s,
      };

  static String _roleTr(String s) => switch (s) {
        'owner' => 'Sahibi',
        'admin' => 'Yonetici',
        'technician' => 'Teknisyen',
        'delivery' => 'Teslimat',
        'finance' => 'Finans',
        'doctor' => 'Hekim',
        _ => 'Uye',
      };
}
