import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../controller/admin/complaint_resolve_controller.dart'; /// شاشة تسوية شكوى — أداة الموظف لإغلاق قضية. /// /// ترتيب الأقسام مقصود: الوقائع أولاً، ثم التحليل المحفوظ، ثم القرار. /// الموظف يقرأ قبل أن يقرّر، لا العكس. class ComplaintResolvePage extends StatelessWidget { const ComplaintResolvePage({super.key, required this.complaint}); final Map complaint; @override Widget build(BuildContext context) { final c = Get.put( ComplaintResolveController(complaint), tag: complaint['id'].toString(), ); return Directionality( textDirection: TextDirection.rtl, child: Scaffold( appBar: AppBar(title: Text('شكوى #${complaint['id']}')), body: ListView( padding: const EdgeInsets.all(16), children: [ _Facts(complaint: complaint), const SizedBox(height: 16), _SavedAnalysis(c: c), const SizedBox(height: 16), _SuggestionCard(c: c), const SizedBox(height: 16), _Decision(c: c), const SizedBox(height: 24), Obx(() => SizedBox( height: 48, child: ElevatedButton.icon( onPressed: c.isSaving.value ? null : () async { if (await c.save()) Get.back(result: true); }, icon: c.isSaving.value ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.check), label: const Text('حفظ التسوية'), ), )), const SizedBox(height: 24), ], ), ), ); } } // ── الوقائع ──────────────────────────────────────────────── class _Facts extends StatelessWidget { const _Facts({required this.complaint}); final Map complaint; @override Widget build(BuildContext context) { return _Section( title: 'الوقائع', icon: Icons.description_outlined, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _row('الرحلة', complaint['ride_id']), _row('النوع', complaint['complaint_type']), _row('تاريخ التقديم', complaint['date_filed']), _row('الحالة الحالية', complaint['statusComplaint']), const Divider(height: 20), Text( complaint['description']?.toString().trim().isNotEmpty == true ? complaint['description'].toString() : 'لا وصف', style: const TextStyle(height: 1.5), ), ], ), ); } Widget _row(String label, dynamic value) => Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Row( children: [ SizedBox( width: 110, child: Text(label, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13)), ), Expanded(child: Text('${value ?? '—'}', style: const TextStyle(fontSize: 13))), ], ), ); } // ── التحليل المحفوظ ──────────────────────────────────────── class _SavedAnalysis extends StatelessWidget { const _SavedAnalysis({required this.c}); final ComplaintResolveController c; @override Widget build(BuildContext context) { if (!c.hasSavedAnalysis) return const SizedBox.shrink(); return _Section( // ‏هذا التحليل أنتجه Gemini وقت تقديم الشكوى وحُفظ في الجدول. // ‏عرضه لا يكلّف نداءً ولا رصيداً — لذلك يظهر دائماً بلا زر. title: 'تحليل وقت التقديم', icon: Icons.auto_awesome_outlined, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (c.savedFault.isNotEmpty || c.savedNature.isNotEmpty) Wrap(spacing: 8, runSpacing: 8, children: [ if (c.savedFault.isNotEmpty) _Chip('المخطئ: ${c.savedFault}'), if (c.savedNature.isNotEmpty) _Chip('الطبيعة: ${c.savedNature}'), ]), if (c.savedSolutions.isNotEmpty) ...[ const SizedBox(height: 12), const Text('حلول مقترحة:', style: TextStyle(fontWeight: FontWeight.bold)), Text(c.savedSolutions, style: const TextStyle(height: 1.5)), ], if (c.savedPassengerReport.isNotEmpty) ...[ const SizedBox(height: 12), const Text('ما أُبلغ به الراكب:', style: TextStyle(fontWeight: FontWeight.bold)), Text(c.savedPassengerReport, style: const TextStyle(height: 1.5)), ], if (c.savedDriverReport.isNotEmpty) ...[ const SizedBox(height: 12), const Text('ما أُبلغ به السائق:', style: TextStyle(fontWeight: FontWeight.bold)), Text(c.savedDriverReport, style: const TextStyle(height: 1.5)), ], ], ), ); } } // ── توصية المبلغ ─────────────────────────────────────────── class _SuggestionCard extends StatelessWidget { const _SuggestionCard({required this.c}); final ComplaintResolveController c; @override Widget build(BuildContext context) { return Obx(() { final s = c.suggestion.value; return _Section( title: 'توصية التسوية', icon: Icons.psychology_outlined, child: s == null ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'يحلّل سجلّ الطرفين وتقييماتهما وتعليقات من تعاملوا معهما،' ' ثم يقترح مبلغاً ورداً للعميل.', style: TextStyle(fontSize: 13, height: 1.5), ), const SizedBox(height: 12), OutlinedButton.icon( onPressed: c.isSuggesting.value ? null : c.requestSuggestion, icon: c.isSuggesting.value ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.lightbulb_outline), label: Text(c.isSuggesting.value ? 'جارٍ التحليل…' : 'اقترح تسوية'), ), ], ) : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Wrap(spacing: 8, runSpacing: 8, children: [ _Chip('المخطئ: ${ComplaintResolveController.faults[s['fault_determination']] ?? s['fault_determination']}'), _Chip('الثقة: ${((s['confidence'] ?? 0) * 100).round()}%'), if ((s['compensation']?['amount'] ?? 0) > 0) _Chip('التعويض: ${s['compensation']['amount']} ${s['compensation']['currency']}') else const _Chip('لا تعويض'), ]), if ((s['customer_reply'] ?? '').toString().isNotEmpty) ...[ const SizedBox(height: 12), const Text('ردّ مقترَح:', style: TextStyle(fontWeight: FontWeight.bold)), Text(s['customer_reply'].toString(), style: const TextStyle(height: 1.5)), ], if ((s['internal_note'] ?? '').toString().isNotEmpty) ...[ const SizedBox(height: 8), Text('ملاحظة داخلية: ${s['internal_note']}', style: const TextStyle(fontSize: 12, color: Colors.grey)), ], const SizedBox(height: 12), // ‏نسخ التوصية بفعل صريح لا تلقائياً: التعبئة الصامتة تجعل // ‏الضغط على "حفظ" موافقةً ضمنية على رقم لم يقرأه أحد. OutlinedButton.icon( onPressed: c.applySuggestion, icon: const Icon(Icons.arrow_downward), label: const Text('انسخ إلى الحقول'), ), ], ), ); }); } } // ── القرار ───────────────────────────────────────────────── class _Decision extends StatelessWidget { const _Decision({required this.c}); final ComplaintResolveController c; @override Widget build(BuildContext context) { return _Section( title: 'القرار', icon: Icons.gavel_outlined, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Obx(() => DropdownButtonFormField( value: c.status.value, decoration: const InputDecoration(labelText: 'الحالة'), items: ComplaintResolveController.statuses .map((s) => DropdownMenuItem(value: s, child: Text(s))) .toList(), onChanged: (v) => c.status.value = v ?? c.status.value, )), const SizedBox(height: 12), Obx(() => DropdownButtonFormField( value: c.reasonCode.value, decoration: const InputDecoration(labelText: 'تصنيف السبب'), items: ComplaintResolveController.reasons.entries .map((e) => DropdownMenuItem(value: e.key, child: Text(e.value))) .toList(), onChanged: (v) => c.reasonCode.value = v, )), const SizedBox(height: 12), Obx(() => DropdownButtonFormField( value: c.faultOn.value, decoration: const InputDecoration(labelText: 'تحديد المسؤولية'), items: ComplaintResolveController.faults.entries .map((e) => DropdownMenuItem(value: e.key, child: Text(e.value))) .toList(), onChanged: (v) => c.faultOn.value = v, )), const SizedBox(height: 12), TextField( controller: c.resolutionCtrl, maxLines: 4, decoration: const InputDecoration( labelText: 'نص القرار / الرد على العميل', alignLabelWithHint: true, ), ), const Divider(height: 28), Obx(() => SwitchListTile( contentPadding: EdgeInsets.zero, title: const Text('صرف تعويض'), subtitle: c.hardCap.value > 0 ? Text('الحد الأقصى ${c.hardCap.value} ${c.currency.value}') : const Text('اضغط "اقترح تسوية" لمعرفة الحد الأقصى'), value: c.compEnabled.value, onChanged: (v) => c.compEnabled.value = v, )), Obx(() => c.compEnabled.value ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextField( controller: c.compAmountCtrl, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: InputDecoration( labelText: 'المبلغ', suffixText: c.currency.value, ), ), const SizedBox(height: 12), DropdownButtonFormField( value: c.compKind.value, decoration: const InputDecoration(labelText: 'النوع'), items: const [ DropdownMenuItem( value: 'refund', child: Text('استرجاع (لا يتجاوز قيمة الرحلة)')), DropdownMenuItem( value: 'goodwill', child: Text('رصيد اعتذار')), ], onChanged: (v) => c.compKind.value = v ?? 'goodwill', ), const SizedBox(height: 12), DropdownButtonFormField( value: c.compBeneficiary.value, decoration: const InputDecoration(labelText: 'المستفيد'), items: const [ DropdownMenuItem(value: 'passenger', child: Text('الراكب')), DropdownMenuItem(value: 'driver', child: Text('السائق')), ], onChanged: (v) => c.compBeneficiary.value = v ?? 'passenger', ), const SizedBox(height: 12), TextField( controller: c.compNoteCtrl, decoration: const InputDecoration(labelText: 'سبب التعويض (اختياري)'), ), ], ) : const SizedBox.shrink()), ], ), ); } } // ── عناصر مشتركة ─────────────────────────────────────────── class _Section extends StatelessWidget { const _Section({required this.title, required this.icon, required this.child}); final String title; final IconData icon; final Widget child; @override Widget build(BuildContext context) { return Card( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(children: [ Icon(icon, size: 18), const SizedBox(width: 8), Text(title, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)), ]), const SizedBox(height: 12), child, ], ), ), ); } } class _Chip extends StatelessWidget { const _Chip(this.text); final String text; @override Widget build(BuildContext context) => Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.08), borderRadius: BorderRadius.circular(20), ), child: Text(text, style: const TextStyle(fontSize: 12)), ); }