import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../app/tema.dart'; import '../cekirdek/sabitler.dart'; import '../galeri/profesyonel_calar.dart'; import '../veri/isar_servisi.dart'; import '../veri/modeller/uretim_kaydi.dart'; import 'uretim_kuyrugu.dart'; /// Aktif üretim işleri paneli — ilerleme çubuklu kartlar. class KuyrukPaneli extends ConsumerWidget { const KuyrukPaneli({super.key, this.tipFiltresi}); final UretimTipi? tipFiltresi; @override Widget build(BuildContext context, WidgetRef ref) { final aktifler = ref.watch(uretimKuyruguProvider); final kayitlar = ref.watch(uretimKayitlariProvider).valueOrNull ?? []; final sonKayitlar = kayitlar .where((k) => tipFiltresi == null || k.tip == tipFiltresi) .take(6) .toList(); if (sonKayitlar.isEmpty) return const SizedBox.shrink(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( children: [ const Icon(Icons.queue_music, size: 16, color: FikoRenkler.neonMor), const SizedBox(width: 6), Text('Üretim Kuyruğu', style: const TextStyle( fontSize: 12.5, fontWeight: FontWeight.w700)), if (aktifler.isNotEmpty) ...[ const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 1), decoration: BoxDecoration( color: FikoRenkler.neonMor.withValues(alpha: 0.18), borderRadius: BorderRadius.circular(8), ), child: Text('${aktifler.length} aktif', style: const TextStyle( fontSize: 10.5, color: FikoRenkler.neonMor)), ), ], ], ), ), SizedBox( height: tipFiltresi == UretimTipi.muzik ? 158 : 86, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: sonKayitlar.length, separatorBuilder: (_, _) => const SizedBox(width: 8), itemBuilder: (_, i) => _IsKarti(kayit: sonKayitlar[i]), ), ), ], ); } } class _IsKarti extends ConsumerWidget { const _IsKarti({required this.kayit}); final UretimKaydi kayit; @override Widget build(BuildContext context, WidgetRef ref) { final aktif = kayit.promptId == null ? null : ref.watch(uretimKuyruguProvider)[kayit.promptId]; final (renk, durumYazi) = switch (kayit.durum) { UretimDurumu.bekliyor => (FikoRenkler.neonAmber, 'Bekliyor'), UretimDurumu.kuyrukta => (FikoRenkler.neonAmber, 'Kuyrukta'), UretimDurumu.uretiliyor => ( FikoRenkler.neonCyan, aktif == null ? 'Üretiliyor' : 'Üretiliyor %${(aktif.ilerleme * 100).round()}' ), UretimDurumu.indiriliyor => (FikoRenkler.neonCyan, 'İndiriliyor'), UretimDurumu.tamamlandi => (FikoRenkler.neonYesil, 'Tamamlandı'), UretimDurumu.hata => (Theme.of(context).colorScheme.error, 'Hata'), UretimDurumu.iptal => (Colors.grey, 'İptal'), }; final calisiyor = kayit.durum == UretimDurumu.uretiliyor || kayit.durum == UretimDurumu.kuyrukta || kayit.durum == UretimDurumu.bekliyor; final muzikCalar = kayit.tip == UretimTipi.muzik && kayit.durum == UretimDurumu.tamamlandi && kayit.ciktiDosyalari.isNotEmpty; return AnimatedContainer( duration: Sabitler.animOrta, width: muzikCalar ? 320 : 230, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Theme.of(context).cardTheme.color, borderRadius: BorderRadius.circular(12), border: Border.all(color: renk.withValues(alpha: 0.4)), boxShadow: calisiyor ? [BoxShadow(color: renk.withValues(alpha: 0.12), blurRadius: 10)] : null, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text(kayit.baslik, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 11.5, fontWeight: FontWeight.w600)), ), _MiniButon( ikon: Icons.edit, tooltip: 'Başlığı değiştir', onTap: () => _adlandir(context), ), if (calisiyor && kayit.promptId != null) _MiniButon( ikon: Icons.close, tooltip: 'İptal et', onTap: () => ref .read(uretimKuyruguProvider.notifier) .iptalEt(kayit.promptId!), ), if (kayit.durum == UretimDurumu.hata) _MiniButon( ikon: Icons.refresh, tooltip: 'Yeniden dene', onTap: () => ref .read(uretimKuyruguProvider.notifier) .yenidenDene(kayit), ), ], ), if (muzikCalar) ...[ const SizedBox(height: 5), ProfesyonelCalar( dosyaYolu: kayit.ciktiDosyalari.first, kompakt: true), ], const Spacer(), if (kayit.durum == UretimDurumu.hata && kayit.hataMesaji != null) Tooltip( message: kayit.hataMesaji!, child: Text(kayit.hataMesaji!, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 10, color: renk)), ) else if (aktif != null && aktif.nodeAdi.isNotEmpty) Text('node: ${aktif.nodeAdi}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10, color: Theme.of(context) .colorScheme .onSurface .withValues(alpha: 0.45))), const SizedBox(height: 6), Row( children: [ Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(4), child: LinearProgressIndicator( value: switch (kayit.durum) { UretimDurumu.tamamlandi => 1, UretimDurumu.uretiliyor => aktif?.ilerleme, UretimDurumu.indiriliyor => null, _ => 0, }, minHeight: 4, color: renk, backgroundColor: renk.withValues(alpha: 0.15), ), ), ), const SizedBox(width: 8), Text(durumYazi, style: TextStyle(fontSize: 10.5, color: renk)), ], ), ], ), ); } void _adlandir(BuildContext context) { final ctrl = TextEditingController(text: kayit.baslik); showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Başlığı Değiştir'), content: TextField( controller: ctrl, autofocus: true, decoration: const InputDecoration(labelText: 'Başlık')), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Vazgeç')), FilledButton( onPressed: () { if (ctrl.text.trim().isNotEmpty) { kayit.baslik = ctrl.text.trim(); isar.writeTxn(() => isar.uretimKaydis.put(kayit)); } Navigator.pop(ctx); }, child: const Text('Kaydet'), ), ], ), ); } } class _MiniButon extends StatelessWidget { const _MiniButon( {required this.ikon, required this.tooltip, required this.onTap}); final IconData ikon; final String tooltip; final VoidCallback onTap; @override Widget build(BuildContext context) { return Tooltip( message: tooltip, child: InkWell( borderRadius: BorderRadius.circular(6), onTap: onTap, child: Padding( padding: const EdgeInsets.all(3), child: Icon(ikon, size: 14), ), ), ); } }