import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';

import '../../../core/providers/auth_provider.dart';
import '../../../core/router/app_router.dart';
import '../../../core/services/realtime_service.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/widgets/tooth_logo.dart';
import '../../shared/location_completion_banner.dart';
import '../../../models/job.dart';
import '../jobs/clinic_jobs_repository.dart';
import '../patients/clinic_patients_repository.dart';

class ClinicDashboardScreen extends ConsumerStatefulWidget {
  const ClinicDashboardScreen({super.key});

  @override
  ConsumerState<ClinicDashboardScreen> createState() =>
      _ClinicDashboardScreenState();
}

class _ClinicDashboardScreenState extends ConsumerState<ClinicDashboardScreen> {
  late Future<_DashboardData> _future;
  UnsubFn? _unsub;
  final Map<String, bool> _actingJobs = {};
  Timer? _reloadDebounce;
  String? _subscribedTenantId;

  @override
  void initState() {
    super.initState();
    _load();
    _ensureRealtimeSubscription();
  }

  @override
  void dispose() {
    _reloadDebounce?.cancel();
    _unsub?.call();
    super.dispose();
  }

  void _ensureRealtimeSubscription() {
    final tenantId = ref.read(authProvider).activeTenant?.tenant.id;
    if (tenantId == null || tenantId == _subscribedTenantId) return;
    _unsub?.call();
    _subscribedTenantId = tenantId;
    _unsub = RealtimeService.instance.watch(
      'jobs',
      filter: "clinic_tenant_id='$tenantId'",
      onEvent: (_) {
        _scheduleReload();
      },
    );
  }

  void _scheduleReload() {
    _reloadDebounce?.cancel();
    _reloadDebounce = Timer(const Duration(milliseconds: 250), () {
      if (mounted) _load();
    });
  }

  void _load() {
    _ensureRealtimeSubscription();
    final tenantId = ref.read(authProvider).activeTenant!.tenant.id;
    setState(() {
      _future = _loadAll(tenantId);
    });
  }

  Future<void> _approveAtClinic(Job job) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(job.patientCode),
        content: Text('${job.prostheticType.label} işini onaylıyor musunuz?'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(ctx, false),
              child: const Text('İptal')),
          FilledButton(
            style: FilledButton.styleFrom(backgroundColor: AppColors.success),
            onPressed: () => Navigator.pop(ctx, true),
            child: const Text('Onayla'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;
    setState(() => _actingJobs[job.id] = true);
    try {
      await ClinicJobsRepository.instance.approveAtClinic(job.id, job);
      _load();
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text('Hata: $e')));
      }
    } finally {
      if (mounted) setState(() => _actingJobs.remove(job.id));
    }
  }

  Future<void> _markDelivered(Job job) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(job.patientCode),
        content: Text(
            '${job.prostheticType.label} işi teslim alındı olarak işaretlensin mi?'),
        actions: [
          TextButton(
              onPressed: () => Navigator.pop(ctx, false),
              child: const Text('İptal')),
          FilledButton(
            onPressed: () => Navigator.pop(ctx, true),
            child: const Text('Teslim Aldım'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;
    setState(() => _actingJobs[job.id] = true);
    try {
      await ClinicJobsRepository.instance.markDelivered(job.id, job);
      _load();
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text('Hata: $e')));
      }
    } finally {
      if (mounted) setState(() => _actingJobs.remove(job.id));
    }
  }

  Future<_DashboardData> _loadAll(String tenantId) async {
    final now = DateTime.now();
    final thisMonthStart = DateTime(now.year, now.month, 1);
    final lastMonthStart = DateTime(now.year, now.month - 1, 1);

    final results = await Future.wait([
      ClinicJobsRepository.instance
          .listOutbound(tenantId, statuses: ['pending'], limit: 200),
      ClinicJobsRepository.instance
          .listOutbound(tenantId, statuses: ['in_progress'], limit: 200),
      ClinicJobsRepository.instance
          .listOutbound(tenantId, statuses: ['sent'], limit: 200),
      ClinicJobsRepository.instance.listOutbound(tenantId, limit: 5),
      ClinicPatientsRepository.instance.listPatients(tenantId, limit: 200),
    ]);
    final thisMonth = await ClinicJobsRepository.instance
        .countDelivered(tenantId, from: thisMonthStart);
    final lastMonth = await ClinicJobsRepository.instance
        .countDelivered(tenantId, from: lastMonthStart, to: thisMonthStart);

    final inProgressJobs = results[1] as List<Job>;
    final sentJobs = results[2] as List<Job>;
    final provaAtClinic = inProgressJobs
        .where((j) => j.location == JobLocation.atClinic)
        .toList();
    final actionJobs = [...provaAtClinic, ...sentJobs];

    return _DashboardData(
      pendingCount: (results[0] as List).length,
      inProgressCount: inProgressJobs.length,
      sentCount: sentJobs.length,
      patientCount: (results[4] as List).length,
      recentJobs: results[3] as List<Job>,
      thisMonthDelivered: thisMonth,
      lastMonthDelivered: lastMonth,
      actionJobs: actionJobs,
    );
  }

  @override
  Widget build(BuildContext context) {
    _ensureRealtimeSubscription();
    final activeTenant = ref.watch(authProvider).activeTenant?.tenant;
    final companyName = activeTenant?.companyName ?? '';
    final showLocationWarning = activeTenant?.hasLocation != true;

    return Scaffold(
      backgroundColor: AppColors.background,
      body: LayoutBuilder(
        builder: (context, constraints) {
          const maxContent = 1040.0;
          final hPad = constraints.maxWidth > maxContent
              ? (constraints.maxWidth - maxContent) / 2
              : 16.0;

          return RefreshIndicator(
            color: AppColors.accent,
            onRefresh: () async => _load(),
            child: FutureBuilder<_DashboardData>(
              future: _future,
              builder: (ctx, snap) {
                if (snap.connectionState == ConnectionState.waiting) {
                  return _DashboardSkeleton(
                      companyName: companyName, hPad: hPad);
                }
                if (snap.hasError) {
                  return _ErrorBody(onRetry: _load);
                }
                final data = snap.data!;
                final isDesktop =
                    MediaQuery.sizeOf(ctx).width > AppLayout.sidebarBreakpoint;
                return CustomScrollView(
                  slivers: [
                    _DashboardHeader(companyName: companyName),
                    if (showLocationWarning)
                      SliverPadding(
                        padding: EdgeInsets.fromLTRB(hPad, 16, hPad, 0),
                        sliver: SliverToBoxAdapter(
                          child: LocationCompletionBanner(
                            title: 'Konum kaydı eksik',
                            description:
                                'Haritada görünmek ve yakın laboratuvar sıralamasında doğru yer almak için işletme konumunu tamamlayın.',
                            buttonLabel: 'Konumu Tamamla',
                            onTap: () => context.go(routeClinicSettings),
                          ),
                        ),
                      ),
                    if (isDesktop)
                      SliverPadding(
                        padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
                        sliver: SliverToBoxAdapter(
                          child: _StatsRow(
                            pending: data.pendingCount,
                            inProgress: data.inProgressCount,
                            sent: data.sentCount,
                            patients: data.patientCount,
                          ),
                        ),
                      ),
                    if (isDesktop) ...[
                      SliverPadding(
                        padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
                        sliver: SliverToBoxAdapter(
                          child: _MonthlyReportSection(data: data)
                              .animate()
                              .fadeIn(duration: 300.ms)
                              .slideY(begin: 0.08, end: 0),
                        ),
                      ),
                      SliverPadding(
                        padding: const EdgeInsets.fromLTRB(16, 8, 16, 0),
                        sliver: SliverToBoxAdapter(
                          child: _GamificationRow(data: data)
                              .animate()
                              .fadeIn(duration: 300.ms, delay: 60.ms)
                              .slideY(begin: 0.08, end: 0),
                        ),
                      ),
                    ],
                    SliverPadding(
                      padding: EdgeInsets.fromLTRB(hPad, 16, hPad, 0),
                      sliver: SliverToBoxAdapter(
                        child: FilledButton.icon(
                          onPressed: () => context.push(routeClinicJobNew),
                          icon: const Icon(Icons.add_rounded, size: 20),
                          label: const Text('Yeni İş Oluştur'),
                          style: FilledButton.styleFrom(
                            minimumSize: const Size(double.infinity, 52),
                            backgroundColor: AppColors.accent,
                          ),
                        )
                            .animate()
                            .fadeIn(duration: 300.ms)
                            .slideY(begin: 0.1, end: 0),
                      ),
                    ),
                    if (data.actionJobs.isNotEmpty)
                      SliverPadding(
                        padding: EdgeInsets.fromLTRB(hPad, 20, hPad, 0),
                        sliver: SliverToBoxAdapter(
                          child: _ActionSection(
                            jobs: data.actionJobs,
                            actingJobs: _actingJobs,
                            onApprove: _approveAtClinic,
                            onDeliver: _markDelivered,
                          )
                              .animate()
                              .fadeIn(duration: 300.ms)
                              .slideY(begin: 0.06, end: 0),
                        ),
                      ),
                    SliverPadding(
                      padding: EdgeInsets.fromLTRB(hPad, 20, hPad, 4),
                      sliver: SliverToBoxAdapter(
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Text('Son İşler',
                                style: Theme.of(context).textTheme.titleMedium),
                            TextButton(
                              onPressed: () => context.go(routeClinicJobs),
                              style: TextButton.styleFrom(
                                foregroundColor: AppColors.accent,
                                padding:
                                    const EdgeInsets.symmetric(horizontal: 8),
                              ),
                              child: const Text('Tümünü Gör'),
                            ),
                          ],
                        ),
                      ),
                    ),
                    if (data.recentJobs.isEmpty)
                      const SliverFillRemaining(
                          hasScrollBody: false, child: _EmptyJobs())
                    else
                      SliverPadding(
                        padding: EdgeInsets.fromLTRB(hPad, 0, hPad, 24),
                        sliver: SliverList.separated(
                          itemCount: data.recentJobs.length,
                          separatorBuilder: (_, __) =>
                              const SizedBox(height: 10),
                          itemBuilder: (ctx, i) =>
                              _JobCard(job: data.recentJobs[i])
                                  .animate(delay: (i * 60).ms)
                                  .fadeIn(duration: 300.ms)
                                  .slideY(begin: 0.12, end: 0),
                        ),
                      ),
                  ],
                );
              },
            ),
          );
        },
      ),
    );
  }
}

class _DashboardData {
  const _DashboardData({
    required this.pendingCount,
    required this.inProgressCount,
    required this.sentCount,
    required this.patientCount,
    required this.recentJobs,
    required this.thisMonthDelivered,
    required this.lastMonthDelivered,
    required this.actionJobs,
  });
  final int pendingCount;
  final int inProgressCount;
  final int sentCount;
  final int patientCount;
  final List<Job> recentJobs;
  final int thisMonthDelivered;
  final int lastMonthDelivered;
  final List<Job> actionJobs;

  int get points => thisMonthDelivered * 10;
  double get changePercent => lastMonthDelivered == 0
      ? (thisMonthDelivered > 0 ? 100 : 0)
      : (thisMonthDelivered - lastMonthDelivered) / lastMonthDelivered * 100;
}

// ── Action Section ───────────────────────────────────────────────────────────

class _ActionSection extends StatelessWidget {
  const _ActionSection({
    required this.jobs,
    required this.actingJobs,
    required this.onApprove,
    required this.onDeliver,
  });

  final List<Job> jobs;
  final Map<String, bool> actingJobs;
  final Future<void> Function(Job) onApprove;
  final Future<void> Function(Job) onDeliver;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Container(
              width: 26,
              height: 26,
              decoration: BoxDecoration(
                  color: AppColors.pending,
                  borderRadius: BorderRadius.circular(7)),
              child: const Icon(Icons.priority_high_rounded,
                  size: 15, color: Colors.white),
            ),
            const SizedBox(width: 8),
            Text('Yapılacaklar',
                style: Theme.of(context)
                    .textTheme
                    .titleMedium
                    ?.copyWith(fontWeight: FontWeight.w700)),
            const SizedBox(width: 8),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2),
              decoration: BoxDecoration(
                  color: AppColors.pending,
                  borderRadius: BorderRadius.circular(10)),
              child: Text('${jobs.length}',
                  style: const TextStyle(
                      fontSize: 11,
                      fontWeight: FontWeight.w800,
                      color: Colors.white)),
            ),
          ],
        ),
        const SizedBox(height: 12),
        ...jobs.asMap().entries.map((entry) => Padding(
              padding: const EdgeInsets.only(bottom: 10),
              child: _ActionJobCard(
                job: entry.value,
                acting: actingJobs[entry.value.id] == true,
                onApprove: () => onApprove(entry.value),
                onDeliver: () => onDeliver(entry.value),
              )
                  .animate(delay: (entry.key * 50).ms)
                  .fadeIn(duration: 250.ms)
                  .slideY(begin: 0.08, end: 0),
            )),
      ],
    );
  }
}

class _ActionJobCard extends StatelessWidget {
  const _ActionJobCard({
    required this.job,
    required this.acting,
    required this.onApprove,
    required this.onDeliver,
  });

  final Job job;
  final bool acting;
  final VoidCallback onApprove;
  final VoidCallback onDeliver;

  bool get _isProva =>
      job.status == JobStatus.inProgress &&
      job.location == JobLocation.atClinic;

  @override
  Widget build(BuildContext context) {
    final isProva = _isProva;
    final borderColor = isProva ? AppColors.pending : AppColors.accent;
    final bgColor = isProva ? AppColors.pendingBg : AppColors.inProgressBg;
    final iconColor = isProva ? AppColors.pending : AppColors.accent;
    final icon =
        isProva ? Icons.rate_review_outlined : Icons.inventory_2_outlined;
    final statusLabel = isProva ? 'Onay Bekliyor' : 'Teslimat Bekliyor';

    return Semantics(
      label: job.patientCode,
      button: true,
      excludeSemantics: true,
      child: Material(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(14),
        child: InkWell(
          onTap: () => context.push('/clinic/jobs/${job.id}'),
          borderRadius: BorderRadius.circular(14),
          child: Container(
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(14),
              border: Border.all(
                  color: borderColor.withValues(alpha: 0.45), width: 1.5),
              boxShadow: [
                BoxShadow(
                    color: Colors.black.withValues(alpha: 0.05),
                    blurRadius: 10,
                    offset: const Offset(0, 3))
              ],
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Padding(
                  padding: const EdgeInsets.fromLTRB(14, 12, 14, 10),
                  child: Row(
                    children: [
                      Container(
                        width: 40,
                        height: 40,
                        decoration: BoxDecoration(
                            color: bgColor,
                            borderRadius: BorderRadius.circular(11)),
                        child: Icon(icon, color: iconColor, size: 19),
                      ),
                      const SizedBox(width: 10),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(job.patientCode,
                                style: const TextStyle(
                                    fontSize: 14,
                                    fontWeight: FontWeight.w700,
                                    color: AppColors.textPrimary)),
                            const SizedBox(height: 2),
                            Text(
                              '${job.prostheticType.label} · ${job.labName ?? 'Lab'}',
                              style: const TextStyle(
                                  fontSize: 12, color: AppColors.textSecondary),
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ],
                        ),
                      ),
                      const SizedBox(width: 8),
                      Container(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 8, vertical: 3),
                        decoration: BoxDecoration(
                            color: bgColor,
                            borderRadius: BorderRadius.circular(8)),
                        child: Text(statusLabel,
                            style: TextStyle(
                                fontSize: 10,
                                fontWeight: FontWeight.w700,
                                color: iconColor)),
                      ),
                    ],
                  ),
                ),
                Container(
                  decoration: BoxDecoration(
                    color: bgColor.withValues(alpha: 0.45),
                    borderRadius: const BorderRadius.only(
                        bottomLeft: Radius.circular(13),
                        bottomRight: Radius.circular(13)),
                  ),
                  padding: const EdgeInsets.fromLTRB(12, 8, 12, 10),
                  child: acting
                      ? const Center(
                          child: Padding(
                            padding: EdgeInsets.symmetric(vertical: 4),
                            child: SizedBox(
                                width: 20,
                                height: 20,
                                child: CircularProgressIndicator(
                                    strokeWidth: 2.5, color: AppColors.accent)),
                          ),
                        )
                      : isProva
                          ? Row(children: [
                              Expanded(
                                child: FilledButton.icon(
                                  onPressed: onApprove,
                                  icon: const Icon(Icons.check_circle_outline,
                                      size: 15),
                                  label: const Text('Onayla',
                                      style: TextStyle(fontSize: 13)),
                                  style: FilledButton.styleFrom(
                                    backgroundColor: AppColors.success,
                                    minimumSize: const Size(0, 36),
                                    tapTargetSize:
                                        MaterialTapTargetSize.shrinkWrap,
                                    padding: const EdgeInsets.symmetric(
                                        horizontal: 12),
                                  ),
                                ),
                              ),
                              const SizedBox(width: 8),
                              OutlinedButton.icon(
                                onPressed: () =>
                                    context.push('/clinic/jobs/${job.id}'),
                                icon: const Icon(Icons.open_in_new_rounded,
                                    size: 14),
                                label: const Text('Detay',
                                    style: TextStyle(fontSize: 13)),
                                style: OutlinedButton.styleFrom(
                                  minimumSize: const Size(0, 36),
                                  tapTargetSize:
                                      MaterialTapTargetSize.shrinkWrap,
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 12),
                                  foregroundColor: AppColors.pending,
                                  side: BorderSide(
                                      color: AppColors.pending
                                          .withValues(alpha: 0.6)),
                                ),
                              ),
                            ])
                          : Row(children: [
                              Expanded(
                                child: FilledButton.icon(
                                  onPressed: onDeliver,
                                  icon: const Icon(Icons.inventory_2_outlined,
                                      size: 15),
                                  label: const Text('Teslim Aldım',
                                      style: TextStyle(fontSize: 13)),
                                  style: FilledButton.styleFrom(
                                    minimumSize: const Size(0, 36),
                                    tapTargetSize:
                                        MaterialTapTargetSize.shrinkWrap,
                                    padding: const EdgeInsets.symmetric(
                                        horizontal: 12),
                                  ),
                                ),
                              ),
                              const SizedBox(width: 8),
                              OutlinedButton.icon(
                                onPressed: () =>
                                    context.push('/clinic/jobs/${job.id}'),
                                icon: const Icon(Icons.open_in_new_rounded,
                                    size: 14),
                                label: const Text('Detay',
                                    style: TextStyle(fontSize: 13)),
                                style: OutlinedButton.styleFrom(
                                  minimumSize: const Size(0, 36),
                                  tapTargetSize:
                                      MaterialTapTargetSize.shrinkWrap,
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 12),
                                  foregroundColor: AppColors.accent,
                                  side: BorderSide(
                                      color: AppColors.accent
                                          .withValues(alpha: 0.6)),
                                ),
                              ),
                            ]),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// ── Monthly Report ──────────────────────────────────────────────────────────

class _MonthlyReportSection extends StatelessWidget {
  const _MonthlyReportSection({required this.data});
  final _DashboardData data;

  @override
  Widget build(BuildContext context) {
    final pct = data.changePercent;
    final isUp = pct >= 0;
    final pctStr = '${isUp ? '+' : ''}${pct.toStringAsFixed(0)}%';
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: AppColors.border),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              const Icon(Icons.bar_chart_rounded,
                  size: 18, color: AppColors.accent),
              const SizedBox(width: 6),
              Text('Aylık Rapor',
                  style: Theme.of(context)
                      .textTheme
                      .titleSmall
                      ?.copyWith(fontWeight: FontWeight.w600)),
            ],
          ),
          const SizedBox(height: 12),
          Row(
            children: [
              Expanded(
                  child: _MonthStat(
                      label: 'Bu Ay',
                      value: data.thisMonthDelivered,
                      highlighted: true)),
              const SizedBox(width: 12),
              Expanded(
                  child: _MonthStat(
                      label: 'Geçen Ay',
                      value: data.lastMonthDelivered,
                      highlighted: false)),
              const SizedBox(width: 12),
              Container(
                padding:
                    const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                decoration: BoxDecoration(
                  color: isUp ? AppColors.successBg : AppColors.cancelledBg,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Icon(
                      isUp
                          ? Icons.trending_up_rounded
                          : Icons.trending_down_rounded,
                      size: 16,
                      color: isUp ? AppColors.success : AppColors.cancelled,
                    ),
                    const SizedBox(width: 4),
                    Text(
                      pctStr,
                      style: TextStyle(
                        fontSize: 13,
                        fontWeight: FontWeight.w700,
                        color: isUp ? AppColors.success : AppColors.cancelled,
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class _MonthStat extends StatelessWidget {
  const _MonthStat(
      {required this.label, required this.value, required this.highlighted});
  final String label;
  final int value;
  final bool highlighted;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
      decoration: BoxDecoration(
        color: highlighted
            ? AppColors.accent.withValues(alpha: 0.06)
            : AppColors.background,
        borderRadius: BorderRadius.circular(8),
        border: highlighted
            ? Border.all(color: AppColors.accent.withValues(alpha: 0.2))
            : null,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label,
              style: const TextStyle(
                  fontSize: 11,
                  color: AppColors.textSecondary,
                  fontWeight: FontWeight.w500)),
          const SizedBox(height: 2),
          Text(
            '$value iş',
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w700,
              color: highlighted ? AppColors.accent : AppColors.textPrimary,
            ),
          ),
        ],
      ),
    );
  }
}

// ── Gamification Row ─────────────────────────────────────────────────────────

const _monthlyGoal = 20;

class _GamificationRow extends StatelessWidget {
  const _GamificationRow({required this.data});
  final _DashboardData data;

  @override
  Widget build(BuildContext context) {
    final progress = (data.thisMonthDelivered / _monthlyGoal).clamp(0.0, 1.0);
    final remaining =
        (_monthlyGoal - data.thisMonthDelivered).clamp(0, _monthlyGoal);
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: AppColors.border),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              const Text('🏆', style: TextStyle(fontSize: 16)),
              const SizedBox(width: 6),
              Text('Aylık Hedef',
                  style: Theme.of(context)
                      .textTheme
                      .titleSmall
                      ?.copyWith(fontWeight: FontWeight.w600)),
              const Spacer(),
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
                decoration: BoxDecoration(
                  color: AppColors.primary.withValues(alpha: 0.08),
                  borderRadius: BorderRadius.circular(6),
                ),
                child: Text(
                  '${data.points} puan',
                  style: const TextStyle(
                      fontSize: 11,
                      fontWeight: FontWeight.w700,
                      color: AppColors.primary),
                ),
              ),
            ],
          ),
          const SizedBox(height: 10),
          ClipRRect(
            borderRadius: BorderRadius.circular(6),
            child: LinearProgressIndicator(
              value: progress,
              minHeight: 8,
              backgroundColor: AppColors.background,
              valueColor: AlwaysStoppedAnimation<Color>(
                progress >= 1.0 ? AppColors.success : AppColors.accent,
              ),
            ),
          ),
          const SizedBox(height: 8),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Text(
                '${data.thisMonthDelivered} / $_monthlyGoal iş teslim edildi',
                style: const TextStyle(
                    fontSize: 12, color: AppColors.textSecondary),
              ),
              Text(
                progress >= 1.0 ? 'Hedef tamamlandı!' : '$remaining iş kaldı',
                style: TextStyle(
                  fontSize: 12,
                  fontWeight: FontWeight.w600,
                  color: progress >= 1.0
                      ? AppColors.success
                      : AppColors.textSecondary,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

// ── Header ──────────────────────────────────────────────────────────────────

class _DashboardHeader extends StatelessWidget {
  const _DashboardHeader({required this.companyName});
  final String companyName;

  static const double _desktopToolbarHeight = 64;

  @override
  Widget build(BuildContext context) {
    final isDesktop =
        MediaQuery.sizeOf(context).width > AppLayout.sidebarBreakpoint;

    if (isDesktop) {
      return SliverAppBar(
        pinned: true,
        toolbarHeight: _desktopToolbarHeight,
        backgroundColor: AppColors.surface,
        surfaceTintColor: Colors.transparent,
        elevation: 0,
        scrolledUnderElevation: 0,
        centerTitle: false,
        automaticallyImplyLeading: false,
        titleSpacing: 0,
        title: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text('Genel Bakış',
                  style: TextStyle(
                      fontSize: 11,
                      color: AppColors.textSecondary.withValues(alpha: 0.8),
                      letterSpacing: 0.3)),
              const Text('Bugünkü Durum',
                  style: TextStyle(
                      fontSize: 17,
                      fontWeight: FontWeight.w700,
                      color: AppColors.textPrimary)),
            ],
          ),
        ),
        actions: [
          IconButton(
            onPressed: () => context.go(routeClinicSettings),
            icon: const Icon(Icons.settings_outlined,
                color: AppColors.textSecondary, size: 22),
          ),
          const SizedBox(width: 8),
        ],
      );
    }

    return SliverAppBar(
      pinned: true,
      expandedHeight: 148,
      backgroundColor: AppColors.primary,
      surfaceTintColor: Colors.transparent,
      shadowColor: Colors.transparent,
      systemOverlayStyle: SystemUiOverlayStyle.light,
      centerTitle: false,
      leadingWidth: 60,
      leading: Padding(
        padding: const EdgeInsets.only(left: 16, top: 8, bottom: 8),
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white.withValues(alpha: 0.15),
            borderRadius: BorderRadius.circular(10),
          ),
          child: const Center(child: ToothLogo(size: 20, color: Colors.white)),
        ),
      ),
      titleSpacing: 8,
      title: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          Text('DLS',
              style: TextStyle(
                  color: Colors.white.withValues(alpha: 0.65),
                  fontSize: 11,
                  fontWeight: FontWeight.w600,
                  letterSpacing: 1.5)),
          Text(companyName,
              style: const TextStyle(
                  color: Colors.white,
                  fontSize: 15,
                  fontWeight: FontWeight.w700),
              maxLines: 1,
              overflow: TextOverflow.ellipsis),
        ],
      ),
      actions: [
        IconButton(
          onPressed: () => context.go(routeClinicSettings),
          icon: const Icon(Icons.settings_outlined,
              color: Colors.white, size: 22),
        ),
      ],
      flexibleSpace: FlexibleSpaceBar(
        collapseMode: CollapseMode.pin,
        background: Container(
          decoration: const BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [AppColors.primary, AppColors.accent],
            ),
          ),
          child: Padding(
            padding: const EdgeInsets.fromLTRB(20, 0, 20, 24),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Text('Genel Bakış',
                    style: TextStyle(
                        color: Colors.white.withValues(alpha: 0.65),
                        fontSize: 12,
                        fontWeight: FontWeight.w500,
                        letterSpacing: 0.5)),
                const SizedBox(height: 4),
                const Text('Bugünkü Durum',
                    style: TextStyle(
                        color: Colors.white,
                        fontSize: 24,
                        fontWeight: FontWeight.w800,
                        letterSpacing: -0.5)),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// ── Stats ────────────────────────────────────────────────────────────────────

class _StatsRow extends StatelessWidget {
  const _StatsRow({
    required this.pending,
    required this.inProgress,
    required this.sent,
    required this.patients,
  });
  final int pending;
  final int inProgress;
  final int sent;
  final int patients;

  @override
  Widget build(BuildContext context) {
    final isWideDesktop =
        MediaQuery.sizeOf(context).width >= AppLayout.wideBreakpoint;

    final c1 = _StatCard(
            label: 'Bekleyen',
            value: '$pending',
            icon: Icons.hourglass_top_rounded,
            color: AppColors.pending,
            bgColor: AppColors.pendingBg)
        .animate()
        .fadeIn(duration: 350.ms)
        .slideY(begin: 0.2, end: 0);
    final c2 = _StatCard(
            label: 'Devam Eden',
            value: '$inProgress',
            icon: Icons.autorenew_rounded,
            color: AppColors.inProgress,
            bgColor: AppColors.inProgressBg)
        .animate(delay: 80.ms)
        .fadeIn(duration: 350.ms)
        .slideY(begin: 0.2, end: 0);
    final c3 = _StatCard(
            label: 'Toplam Hasta',
            value: '$patients',
            icon: Icons.people_outline_rounded,
            color: AppColors.success,
            bgColor: AppColors.successBg)
        .animate(delay: 160.ms)
        .fadeIn(duration: 350.ms)
        .slideY(begin: 0.2, end: 0);

    // Wide desktop (≥ 1100px): 4 cards side by side — full lifecycle view.
    if (isWideDesktop) {
      final c4 = _StatCard(
              label: 'Klinik\'te',
              value: '$sent',
              icon: Icons.local_hospital_outlined,
              color: AppColors.accent,
              bgColor: AppColors.inProgressBg)
          .animate(delay: 120.ms)
          .fadeIn(duration: 350.ms)
          .slideY(begin: 0.2, end: 0);
      return Row(
        children: [
          Expanded(child: c1),
          const SizedBox(width: 12),
          Expanded(child: c2),
          const SizedBox(width: 12),
          Expanded(child: c4),
          const SizedBox(width: 12),
          Expanded(child: c3),
        ],
      );
    }

    // Mobile + narrow sidebar (< 1100px): 2+1 column layout.
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Row(
          children: [
            Expanded(child: c1),
            const SizedBox(width: 12),
            Expanded(child: c2),
          ],
        ),
        const SizedBox(height: 12),
        c3,
      ],
    );
  }
}

class _StatCard extends StatelessWidget {
  const _StatCard({
    required this.label,
    required this.value,
    required this.icon,
    required this.color,
    required this.bgColor,
  });
  final String label;
  final String value;
  final IconData icon;
  final Color color;
  final Color bgColor;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: AppColors.border),
        boxShadow: [
          BoxShadow(
              color: Colors.black.withValues(alpha: 0.06),
              blurRadius: 12,
              offset: const Offset(0, 4))
        ],
      ),
      child: Row(
        children: [
          Container(
            width: 44,
            height: 44,
            decoration: BoxDecoration(
                color: bgColor, borderRadius: BorderRadius.circular(12)),
            child: Icon(icon, color: color, size: 22),
          ),
          const SizedBox(width: 12),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(value,
                  style: TextStyle(
                      fontSize: 28,
                      fontWeight: FontWeight.w800,
                      color: color,
                      height: 1)),
              const SizedBox(height: 3),
              Text(label,
                  style: const TextStyle(
                      fontSize: 12,
                      color: AppColors.textSecondary,
                      fontWeight: FontWeight.w500)),
            ],
          ),
        ],
      ),
    );
  }
}

// ── Job Card ─────────────────────────────────────────────────────────────────

class _JobCard extends StatelessWidget {
  const _JobCard({required this.job});
  final Job job;

  @override
  Widget build(BuildContext context) {
    final due = job.dueDate;
    final isOverdue = due != null && due.isBefore(DateTime.now());
    final dueText = due != null
        ? '${due.day.toString().padLeft(2, '0')}.${due.month.toString().padLeft(2, '0')}.${due.year}'
        : null;

    final statusColor = _statusColor(job.status);
    final statusBg = _statusBg(job.status);

    return Semantics(
      label: job.patientCode,
      button: true,
      excludeSemantics: true,
      child: Material(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(14),
        child: InkWell(
          onTap: () => context.push('/clinic/jobs/${job.id}'),
          borderRadius: BorderRadius.circular(14),
          child: Container(
            padding: const EdgeInsets.all(14),
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(14),
                border: Border.all(color: AppColors.border)),
            child: Row(
              children: [
                Container(
                  width: 46,
                  height: 46,
                  decoration: BoxDecoration(
                      color: statusBg, borderRadius: BorderRadius.circular(12)),
                  child: Icon(Icons.work_outline_rounded,
                      color: statusColor, size: 22),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(job.patientCode,
                          style: const TextStyle(
                              fontSize: 15,
                              fontWeight: FontWeight.w600,
                              color: AppColors.textPrimary)),
                      const SizedBox(height: 2),
                      Text(job.labName ?? 'Laboratuvar',
                          style: const TextStyle(
                              fontSize: 13, color: AppColors.textSecondary)),
                      const SizedBox(height: 6),
                      Wrap(
                        spacing: 6,
                        children: [
                          _Tag(
                              label: job.prostheticType.label,
                              color: AppColors.inProgress,
                              bg: AppColors.inProgressBg),
                          _Tag(
                              label: job.status.label,
                              color: statusColor,
                              bg: statusBg),
                        ],
                      ),
                    ],
                  ),
                ),
                if (dueText != null) ...[
                  const SizedBox(width: 8),
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Icon(Icons.calendar_today_outlined,
                          size: 13,
                          color: isOverdue
                              ? AppColors.cancelled
                              : AppColors.textMuted),
                      const SizedBox(height: 3),
                      Text(
                        dueText,
                        style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w500,
                            color: isOverdue
                                ? AppColors.cancelled
                                : AppColors.textSecondary),
                      ),
                    ],
                  ),
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }

  Color _statusColor(JobStatus s) {
    switch (s) {
      case JobStatus.pending:
        return AppColors.pending;
      case JobStatus.inProgress:
        return AppColors.inProgress;
      case JobStatus.sent:
        return AppColors.accent;
      case JobStatus.delivered:
        return AppColors.success;
      case JobStatus.cancelled:
        return AppColors.cancelled;
    }
  }

  Color _statusBg(JobStatus s) {
    switch (s) {
      case JobStatus.pending:
        return AppColors.pendingBg;
      case JobStatus.inProgress:
        return AppColors.inProgressBg;
      case JobStatus.sent:
        return AppColors.inProgressBg;
      case JobStatus.delivered:
        return AppColors.successBg;
      case JobStatus.cancelled:
        return AppColors.cancelledBg;
    }
  }
}

class _Tag extends StatelessWidget {
  const _Tag({required this.label, required this.color, required this.bg});
  final String label;
  final Color color;
  final Color bg;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
      decoration:
          BoxDecoration(color: bg, borderRadius: BorderRadius.circular(6)),
      child: Text(label,
          style: TextStyle(
              fontSize: 11, fontWeight: FontWeight.w600, color: color)),
    );
  }
}

// ── Empty / Error / Skeleton ─────────────────────────────────────────────────

class _EmptyJobs extends StatelessWidget {
  const _EmptyJobs();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(40),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            width: 72,
            height: 72,
            decoration: BoxDecoration(
                color: AppColors.inProgressBg,
                borderRadius: BorderRadius.circular(20)),
            child: const Icon(Icons.work_off_outlined,
                color: AppColors.inProgress, size: 32),
          ),
          const SizedBox(height: 16),
          const Text('Henüz iş yok',
              style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w600,
                  color: AppColors.textPrimary)),
          const SizedBox(height: 6),
          const Text(
            'Yeni iş oluşturduğunuzda\nburada görünecek',
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 13, color: AppColors.textSecondary),
          ),
        ],
      ),
    );
  }
}

class _ErrorBody extends StatelessWidget {
  const _ErrorBody({required this.onRetry});
  final VoidCallback onRetry;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 64,
              height: 64,
              decoration: BoxDecoration(
                  color: AppColors.cancelledBg,
                  borderRadius: BorderRadius.circular(16)),
              child: const Icon(Icons.wifi_off_rounded,
                  color: AppColors.cancelled, size: 30),
            ),
            const SizedBox(height: 16),
            const Text('Bağlantı hatası',
                style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w600,
                    color: AppColors.textPrimary)),
            const SizedBox(height: 12),
            FilledButton.icon(
                onPressed: onRetry,
                icon: const Icon(Icons.refresh_rounded, size: 18),
                label: const Text('Tekrar Dene')),
          ],
        ),
      ),
    );
  }
}

class _DashboardSkeleton extends StatelessWidget {
  const _DashboardSkeleton({required this.companyName, required this.hPad});
  final String companyName;
  final double hPad;

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      physics: const NeverScrollableScrollPhysics(),
      slivers: [
        _DashboardHeader(companyName: companyName),
        SliverPadding(
          padding: EdgeInsets.fromLTRB(hPad, 16, hPad, 0),
          sliver: const SliverToBoxAdapter(
            child: Column(
              children: [
                Row(children: [
                  Expanded(child: _ShimmerBox(height: 84, radius: 16)),
                  SizedBox(width: 12),
                  Expanded(child: _ShimmerBox(height: 84, radius: 16)),
                ]),
                SizedBox(height: 12),
                _ShimmerBox(height: 84, radius: 16),
              ],
            ),
          ),
        ),
        SliverPadding(
          padding: EdgeInsets.fromLTRB(hPad, 8, hPad, 0),
          sliver: SliverList.builder(
            itemCount: 4,
            itemBuilder: (_, i) => const Padding(
                padding: EdgeInsets.only(bottom: 10),
                child: _ShimmerBox(height: 92, radius: 14)),
          ),
        ),
      ],
    );
  }
}

class _ShimmerBox extends StatefulWidget {
  const _ShimmerBox({required this.height, required this.radius});
  final double height;
  final double radius;

  @override
  State<_ShimmerBox> createState() => _ShimmerBoxState();
}

class _ShimmerBoxState extends State<_ShimmerBox>
    with SingleTickerProviderStateMixin {
  late AnimationController _ctrl;
  late Animation<double> _anim;

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 1100))
      ..repeat(reverse: true);
    _anim = CurvedAnimation(parent: _ctrl, curve: Curves.easeInOut);
  }

  @override
  void dispose() {
    _ctrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _anim,
      builder: (_, __) => Container(
        height: widget.height,
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(widget.radius),
            color: Color.lerp(
                const Color(0xFFE2E8F0), const Color(0xFFF1F5F9), _anim.value)),
      ),
    );
  }
}
