import 'package:flutter/material.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/gradient_app_bar.dart';
import '../../../core/widgets/pill_tabs.dart';
import '../../../models/job.dart';
import 'clinic_jobs_repository.dart';

enum _JobSort { newestFirst, oldestFirst, byDueDate, byType }

const _kSortLabels = [
  'Yeniden Eskiye',
  'Eskiden Yeniye',
  'Vade Tarihine Göre',
  'Türe Göre',
];

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

  @override
  ConsumerState<ClinicJobsScreen> createState() => _ClinicJobsScreenState();
}

class _ClinicJobsScreenState extends ConsumerState<ClinicJobsScreen>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final _searchController = TextEditingController();
  String _searchQuery = '';
  _JobSort _sort = _JobSort.newestFirst;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 5, vsync: this);
    _tabController.addListener(() {
      if (mounted) setState(() {});
    });
  }

  @override
  void dispose() {
    _tabController.dispose();
    _searchController.dispose();
    super.dispose();
  }

  void _onSearchChanged(String value) {
    setState(() => _searchQuery = value);
  }

  Future<void> _showSortOptions() async {
    final result = await showSortSheet(
      context,
      title: 'Sıralama',
      options: _kSortLabels,
      current: _sort.index,
    );
    if (result != null) {
      setState(() => _sort = _JobSort.values[result]);
    }
  }

  @override
  Widget build(BuildContext context) {
    final isSortActive = _sort != _JobSort.newestFirst;

    return Scaffold(
      backgroundColor: AppColors.background,
      appBar: GradientAppBar(
        title: 'İşlerim',
        category: 'KLİNİK',
        searchController: _searchController,
        onSearchChanged: _onSearchChanged,
        searchHint: 'Protokol, laboratuvar veya tür ara...',
        actions: [
          IconButton(
            onPressed: _showSortOptions,
            tooltip: 'Sırala',
            icon: Badge(
              isLabelVisible: isSortActive,
              smallSize: 8,
              backgroundColor: AppColors.accent,
              child: const Icon(Icons.sort_rounded),
            ),
          ),
          if (ref.watch(authProvider).activeTenant?.canCreateJobs ?? true)
            IconButton(
              onPressed: () => context.push(routeClinicJobNew),
              tooltip: 'Yeni İş',
              icon: const Icon(Icons.add_rounded),
            ),
        ],
      ),
      body: Column(
        children: [
          PillTabs(
            tabs: const ['Tümü', 'Onay Bekleyen', 'Lab\'da', 'Teslimat', 'Teslim Alındı'],
            selected: _tabController.index,
            onSelect: (i) => _tabController.animateTo(i),
          ),
          Expanded(
            child: TabBarView(
              controller: _tabController,
              children: [
                _JobsTab(
                  statuses: const ['pending', 'in_progress', 'sent', 'delivered'],
                  searchQuery: _searchQuery,
                  sort: _sort,
                ),
                _JobsTab(
                  statuses: const ['in_progress'],
                  location: 'at_clinic',
                  searchQuery: _searchQuery,
                  sort: _sort,
                ),
                _JobsTab(
                  filterExtra: 'status = "pending" || (status = "in_progress" && location = "at_lab")',
                  searchQuery: _searchQuery,
                  sort: _sort,
                ),
                _JobsTab(
                  statuses: const ['sent'],
                  searchQuery: _searchQuery,
                  sort: _sort,
                ),
                _JobsTab(
                  statuses: const ['delivered'],
                  searchQuery: _searchQuery,
                  sort: _sort,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _JobsTab extends ConsumerStatefulWidget {
  const _JobsTab({
    this.statuses,
    this.location,
    this.filterExtra,
    required this.searchQuery,
    required this.sort,
  });

  final List<String>? statuses;
  final String? location;
  final String? filterExtra;
  final String searchQuery;
  final _JobSort sort;

  @override
  ConsumerState<_JobsTab> createState() => _JobsTabState();
}

class _JobsTabState extends ConsumerState<_JobsTab> {
  final List<Job> _jobs = [];
  bool _isLoading = false;
  bool _hasMore = true;
  int _page = 1;
  static const _limit = 20;
  String? _error;
  late UnsubFn _unsub;

  final _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _load();
    _scrollController.addListener(_onScroll);
    final tenantId = ref.read(authProvider).activeTenant!.tenant.id;
    _unsub = RealtimeService.instance.watch(
      'jobs',
      filter: 'clinic_tenant_id="$tenantId"',
      onEvent: (_) { if (mounted) _load(); },
    );
  }

  @override
  void dispose() {
    _unsub();
    _scrollController.dispose();
    super.dispose();
  }

  void _onScroll() {
    if (_scrollController.position.pixels >=
            _scrollController.position.maxScrollExtent - 200 &&
        !_isLoading &&
        _hasMore) {
      _loadMore();
    }
  }

  Future<void> _load() async {
    if (_isLoading) return;
    setState(() {
      _isLoading = true;
      _error = null;
      _page = 1;
      _jobs.clear();
      _hasMore = true;
    });
    await _fetch();
  }

  Future<void> _loadMore() async {
    if (_isLoading || !_hasMore) return;
    _page++;
    await _fetch();
  }

  Future<void> _fetch() async {
    setState(() => _isLoading = true);
    try {
      final tenantId = ref.read(authProvider).activeTenant!.tenant.id;
      final results = await ClinicJobsRepository.instance.listOutbound(
        tenantId,
        statuses: widget.statuses,
        location: widget.location,
        filterExtra: widget.filterExtra,
        page: _page,
        limit: _limit,
      );
      setState(() {
        _jobs.addAll(results);
        _hasMore = results.length == _limit;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _error = e.toString();
        _isLoading = false;
      });
    }
  }

  List<Job> get _filtered {
    var list = _jobs.toList();

    final q = widget.searchQuery.toLowerCase().trim();
    if (q.isNotEmpty) {
      list = list.where((j) {
        return j.patientCode.toLowerCase().contains(q) ||
            (j.patientName?.toLowerCase().contains(q) ?? false) ||
            (j.labName?.toLowerCase().contains(q) ?? false) ||
            j.prostheticType.label.toLowerCase().contains(q) ||
            (j.prostheticName?.toLowerCase().contains(q) ?? false);
      }).toList();
    }

    switch (widget.sort) {
      case _JobSort.newestFirst:
        list.sort((a, b) => b.dateCreated.compareTo(a.dateCreated));
      case _JobSort.oldestFirst:
        list.sort((a, b) => a.dateCreated.compareTo(b.dateCreated));
      case _JobSort.byDueDate:
        list.sort((a, b) {
          if (a.dueDate == null && b.dueDate == null) return 0;
          if (a.dueDate == null) return 1;
          if (b.dueDate == null) return -1;
          return a.dueDate!.compareTo(b.dueDate!);
        });
      case _JobSort.byType:
        list.sort(
            (a, b) => a.prostheticType.label.compareTo(b.prostheticType.label));
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    if (_error != null && _jobs.isEmpty) {
      return Center(
        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),
            Text('Hata: $_error',
                style: const TextStyle(color: AppColors.textSecondary)),
            const SizedBox(height: 12),
            FilledButton.icon(
              onPressed: _load,
              icon: const Icon(Icons.refresh_rounded, size: 18),
              label: const Text('Tekrar Dene'),
            ),
          ],
        ),
      );
    }

    if (_isLoading && _jobs.isEmpty) {
      return const Center(
          child: CircularProgressIndicator(color: AppColors.accent));
    }

    final filtered = _filtered;

    if (filtered.isEmpty) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          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),
            Text(
              widget.searchQuery.isNotEmpty
                  ? 'Sonuç bulunamadı'
                  : 'Henüz iş yok',
              style: const TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w600,
                  color: AppColors.textPrimary),
            ),
          ],
        ),
      );
    }

    return RefreshIndicator(
      color: AppColors.accent,
      onRefresh: _load,
      child: ListView.builder(
        controller: _scrollController,
        padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
        itemCount:
            filtered.length + (_hasMore && widget.searchQuery.isEmpty ? 1 : 0),
        itemBuilder: (context, index) {
          if (index == filtered.length) {
            return const Padding(
              padding: EdgeInsets.all(16),
              child: Center(
                  child: CircularProgressIndicator(color: AppColors.accent)),
            );
          }
          final job = filtered[index];
          return Padding(
            padding: const EdgeInsets.only(bottom: 10),
            child: _JobListCard(
              job: job,
              onTap: () => context.push('/clinic/jobs/${job.id}'),
            ),
          );
        },
      ),
    );
  }
}

class _JobListCard extends StatelessWidget {
  const _JobListCard({required this.job, required this.onTap});

  final Job job;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final title = job.patientName?.trim().isNotEmpty == true
        ? job.patientName!
        : job.patientCode;
    final statusColor = _statusColor(job);
    final statusBg = _statusBg(job);
    final isOverdue =
        job.dueDate != null && job.dueDate!.isBefore(DateTime.now());

    return Semantics(
      label: title,
      button: true,
      excludeSemantics: true,
      child: Material(
      color: AppColors.surface,
      borderRadius: BorderRadius.circular(14),
      child: InkWell(
        onTap: onTap,
        borderRadius: BorderRadius.circular(14),
        child: Container(
          padding: const EdgeInsets.all(14),
          decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(14),
              border: Border.all(color: AppColors.border),
              boxShadow: [
                BoxShadow(
                    color: Colors.black.withValues(alpha: 0.04),
                    blurRadius: 8,
                    offset: const Offset(0, 2))
              ]),
          child: Row(
            children: [
              Container(
                width: 44,
                height: 44,
                decoration: BoxDecoration(
                    color: statusBg,
                    borderRadius: BorderRadius.circular(12)),
                child: Icon(Icons.medical_services_outlined,
                    color: statusColor, size: 20),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        Expanded(
                          child: Text(
                            title,
                            style: const TextStyle(
                                fontSize: 15,
                                fontWeight: FontWeight.w600,
                                color: AppColors.textPrimary),
                          ),
                        ),
                        _StatusBadge(status: job.status, location: job.location),
                      ],
                    ),
                    const SizedBox(height: 3),
                    Text(
                        job.prostheticName?.isNotEmpty == true
                            ? '${job.prostheticType.label} · ${job.prostheticName}'
                            : job.prostheticType.label,
                        style: const TextStyle(
                            fontSize: 12, color: AppColors.textSecondary)),
                    if (job.patientName?.isNotEmpty == true) ...[
                      const SizedBox(height: 2),
                      Text(
                        job.patientCode,
                        style: const TextStyle(
                            fontSize: 12, color: AppColors.textMuted),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                    if (job.labName != null) ...[
                      const SizedBox(height: 2),
                      Text(
                        job.labName!,
                        style: const TextStyle(
                            fontSize: 12, color: AppColors.textMuted),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                    if (job.dueDate != null) ...[
                      const SizedBox(height: 2),
                      Row(
                        children: [
                          Icon(Icons.calendar_today_outlined,
                              size: 11,
                              color: isOverdue
                                  ? AppColors.cancelled
                                  : AppColors.textMuted),
                          const SizedBox(width: 3),
                          Text(
                            _fmt(job.dueDate!),
                            style: TextStyle(
                              fontSize: 12,
                              color: isOverdue
                                  ? AppColors.cancelled
                                  : AppColors.textMuted,
                              fontWeight: isOverdue
                                  ? FontWeight.w600
                                  : FontWeight.normal,
                            ),
                          ),
                        ],
                      ),
                    ],
                  ],
                ),
              ),
              const SizedBox(width: 8),
              const Icon(Icons.chevron_right,
                  color: AppColors.textMuted, size: 20),
            ],
          ),
        ),
      ),
      ),
    );
  }

  String _fmt(DateTime d) =>
      '${d.day.toString().padLeft(2, '0')}.${d.month.toString().padLeft(2, '0')}.${d.year}';

  Color _statusColor(Job job) {
    if (job.status == JobStatus.inProgress && job.location == JobLocation.atClinic) return AppColors.pending;
    switch (job.status) {
      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(Job job) {
    if (job.status == JobStatus.inProgress && job.location == JobLocation.atClinic) return AppColors.pendingBg;
    switch (job.status) {
      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 _StatusBadge extends StatelessWidget {
  const _StatusBadge({required this.status, required this.location});

  final JobStatus status;
  final JobLocation location;

  String get _label {
    if (status == JobStatus.inProgress && location == JobLocation.atClinic) return 'Onay Bekliyor';
    if (status == JobStatus.sent) return 'Teslimat Bekliyor';
    return status.label;
  }

  Color get _color {
    if (status == JobStatus.inProgress && location == JobLocation.atClinic) return AppColors.pending;
    switch (status) {
      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 get _bg {
    if (status == JobStatus.inProgress && location == JobLocation.atClinic) return AppColors.pendingBg;
    switch (status) {
      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;
    }
  }

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