import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import '../api/AbsensiApi.dart';
import 'package:geolocator/geolocator.dart';
import '../api/LoginApi.dart';
import 'package:intl/intl.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest.dart' as tz;

// ── Palette ───────────────────────────────────────────────────────────────────
const _bg        = Color(0xFFF9FAFB);
const _bg1       = Color(0xFFFFFFFF);
const _bg2       = Color(0xFFF3F4F6);
const _green     = Color(0xFF10B981);
const _greenDim  = Color(0x1A10B981);
const _greenGlow = Color(0x4D10B981);
const _cyan      = Color(0xFF06B6D4);
const _cyanDim   = Color(0x1A06B6D4);
const _amber     = Color(0xFFF59E0B);
const _amberDim  = Color(0x1AF59E0B);
const _rose      = Color(0xFFEF4444);
const _roseDim   = Color(0x1AEF4444);
const _t1        = Color(0xFF111827);
const _t2        = Color(0xFF6B7280);
const _t3        = Color(0xFF9CA3AF);
const _line2     = Color(0xFFE5E7EB);

class AbsensiScreen extends StatefulWidget {
  const AbsensiScreen({Key? key}) : super(key: key);

  @override
  State<AbsensiScreen> createState() => _AbsensiScreenState();
}

class _AbsensiScreenState extends State<AbsensiScreen>
    with TickerProviderStateMixin {
  final AbsensiApi  _absensiApi = AbsensiApi();
  final ApiService  _apiService = ApiService();
  final ImagePicker _picker     = ImagePicker();

  bool _isLoading          = true;
  bool _isLoadingRiwayat   = false;
  bool _isLoadingRekap     = false;
  bool _isProcessing       = false;

  Map<String, dynamic>?      _userData;
  Map<String, dynamic>?      _statusAbsensi;
  int?                       _idTeknisi;

  List<Map<String, dynamic>> _riwayat      = [];
  Map<String, dynamic>       _rekap        = {};
  Map<int, String>           _kalenderData = {};

  String   _filterStatus  = 'semua';
  DateTime _bulanRiwayat  = DateTime(DateTime.now().year, DateTime.now().month);
  DateTime _bulanRekap    = DateTime(DateTime.now().year, DateTime.now().month);
  DateTime _bulanKalender = DateTime(DateTime.now().year, DateTime.now().month);

  late TabController       _tabCtrl;
  late AnimationController _pulseCtrl;
  late Animation<double>   _pulseAnim;

  final List<Map<String, dynamic>> _statusOptions = [
    {'label': 'Hadir', 'value': 'hadir', 'icon': Icons.check_circle_rounded,  'color': _green},
    {'label': 'Izin',  'value': 'izin',  'icon': Icons.event_busy_rounded,     'color': _amber},
    {'label': 'Sakit', 'value': 'sakit', 'icon': Icons.local_hospital_rounded, 'color': _rose},
  ];

  @override
  void initState() {
    super.initState();
    tz.initializeTimeZones();
    _tabCtrl   = TabController(length: 2, vsync: this);
    _pulseCtrl = AnimationController(
        vsync: this, duration: const Duration(seconds: 2))
      ..repeat(reverse: true);
    _pulseAnim = Tween<double>(begin: 0.4, end: 1.0).animate(
        CurvedAnimation(parent: _pulseCtrl, curve: Curves.easeInOut));

    _tabCtrl.addListener(() {
      if (!_tabCtrl.indexIsChanging) {
        if (_tabCtrl.index == 1) {
          if (_rekap.isEmpty) _fetchRekap();
          if (_riwayat.isEmpty) _fetchRiwayat();
        }
      }
    });

    _loadData();
  }

  @override
  void dispose() {
    _tabCtrl.dispose();
    _pulseCtrl.dispose();
    super.dispose();
  }

  // ── API calls ─────────────────────────────────────────────────────────────

  Future<void> _loadData() async {
    setState(() => _isLoading = true);
    final res = await _apiService.getProfile();
    if (res['success'] == true && res['data'] != null) {
      setState(() {
        _userData  = res['data'];
        _idTeknisi = res['data']['teknisi']?['id_teknisi'];
      });
      if (_idTeknisi != null) await _checkStatusAbsensi();
    }
    setState(() => _isLoading = false);
  }

  Future<void> _checkStatusAbsensi() async {
    if (_idTeknisi == null) return;
    final r = await _absensiApi.checkStatus(_idTeknisi!);
    if (r['success'] == true) setState(() => _statusAbsensi = r['data']);
  }

  /// Ambil riwayat absensi dari API berdasarkan bulan yang dipilih
  Future<void> _fetchRiwayat() async {
    if (_idTeknisi == null) return;
    setState(() => _isLoadingRiwayat = true);
    try {
      final r = await _absensiApi.getRiwayat(
        idTeknisi: _idTeknisi!,
        bulan: _bulanRekap.month, // Menggunakan bulan dari rekap agar sinkron
        tahun: _bulanRekap.year,
      );
      if (r['success'] == true) {
        setState(() {
          _riwayat = List<Map<String, dynamic>>.from(r['data'] ?? []);
        });
      }
    } catch (_) {
    } finally {
      setState(() {
        _isLoadingRiwayat = false;
        // Update kalender data dari riwayat
        _kalenderData.clear();
        for (var item in _riwayat) {
          final tgl = item['tanggal'] as String?;
          if (tgl != null) {
            final date = DateTime.parse(tgl);
            _kalenderData[date.day] = item['status'] as String;
          }
        }
      });
    }
  }

  /// Ambil rekap bulanan dari API
  Future<void> _fetchRekap() async {
    if (_idTeknisi == null) return;
    setState(() => _isLoadingRekap = true);
    try {
      final r = await _absensiApi.getRekap(
        idTeknisi: _idTeknisi!,
        bulan: _bulanRekap.month,
        tahun: _bulanRekap.year,
      );
      if (r['success'] == true) {
        setState(() => _rekap = Map<String, dynamic>.from(r['data'] ?? {}));
      }
    } catch (_) {
    } finally {
      setState(() => _isLoadingRekap = false);
    }
  }

  // ── Absen handlers ────────────────────────────────────────────────────────

  Future<Position?> _getCurrentPosition() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      _toast('Layanan lokasi dinonaktifkan.', ok: false);
      return null;
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        _toast('Izin lokasi ditolak', ok: false);
        return null;
      }
    }

    if (permission == LocationPermission.deniedForever) {
      _toast('Izin lokasi ditolak secara permanen.', ok: false);
      return null;
    }

    _toast('Mencari lokasi GPS...', ok: true);
    return await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
  }

  Future<void> _handleAbsenMasuk() async {
    if (_idTeknisi == null) { _toast('ID Teknisi tidak ditemukan', ok: false); return; }
    final result = await _showStatusDialog('Absen Masuk');
    if (result == null) return;
    final status = result['status'] as String;
    final ket    = result['keterangan'] as String?;
    XFile? image;
    if (status == 'hadir') {
      image = await _pickImage();
      if (image == null) { _toast('Foto diperlukan untuk status Hadir', ok: false); return; }
    }

    Position? position = await _getCurrentPosition();
    if (position == null) return;

    setState(() => _isProcessing = true);
    final r = await _absensiApi.absenMasuk(
        idTeknisi: _idTeknisi!, fotoAbsenMasuk: image,
        status: status, keterangan: ket,
        latitude: position.latitude, longitude: position.longitude);
    setState(() => _isProcessing = false);
    if (r['success'] == true) {
      _toast('Absen masuk berhasil!', ok: true);
      await _checkStatusAbsensi();
      _fetchRekap(); // Refresh rekap
      _fetchRiwayat(); // Refresh riwayat
    } else {
      _toast(r['message'] ?? 'Gagal absen masuk', ok: false);
    }
  }

  Future<void> _handleAbsenKeluar() async {
    if (_idTeknisi == null) { _toast('ID Teknisi tidak ditemukan', ok: false); return; }
    
    // Langsung minta foto tanpa dialog status untuk absen keluar
    final image = await _pickImage();
    if (image == null) {
      _toast('Foto diperlukan untuk Absen Keluar', ok: false);
      return;
    }

    Position? position = await _getCurrentPosition();
    if (position == null) return;

    setState(() => _isProcessing = true);
    final r = await _absensiApi.absenKeluar(
        idTeknisi: _idTeknisi!, 
        fotoAbsenKeluar: image,
        status: 'hadir', // Otomatis hadir jika absen keluar
        keterangan: null,
        latitude: position.latitude, longitude: position.longitude);
    
    setState(() => _isProcessing = false);
    if (r['success'] == true) {
      _toast('Absen keluar berhasil!', ok: true);
      await _checkStatusAbsensi();
      _fetchRekap(); // Refresh rekap
      _fetchRiwayat(); // Refresh riwayat
    } else {
      _toast(r['message'] ?? 'Gagal absen keluar', ok: false);
    }
  }

  Future<XFile?> _pickImage() async {
    if (kIsWeb) return _picker.pickImage(source: ImageSource.gallery, imageQuality: 70);
    final src = await _showImageSourceDialog();
    if (src == null) return null;
    return _picker.pickImage(source: src, imageQuality: 70);
  }

  // ── Dialogs ───────────────────────────────────────────────────────────────

  Future<ImageSource?> _showImageSourceDialog() {
    return showDialog<ImageSource>(
      context: context,
      builder: (ctx) => Dialog(
        backgroundColor: _bg1,
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
            side: const BorderSide(color: _line2)),
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(mainAxisSize: MainAxisSize.min, children: [
            Container(width: 48, height: 48,
                decoration: BoxDecoration(color: _cyanDim,
                    borderRadius: BorderRadius.circular(13),
                    border: Border.all(color: _cyan.withOpacity(0.3))),
                child: const Icon(Icons.camera_alt_rounded, color: _cyan, size: 22)),
            const SizedBox(height: 12),
            const Text('Pilih Sumber Foto', style: TextStyle(
                fontSize: 16, fontWeight: FontWeight.w700, color: _t1)),
            const SizedBox(height: 18),
            _srcBtn(Icons.camera_alt_rounded, 'Kamera', _cyan, _cyanDim,
                () => Navigator.pop(ctx, ImageSource.camera)),
            const SizedBox(height: 8),
            _srcBtn(Icons.photo_library_rounded, 'Galeri', _green, _greenDim,
                () => Navigator.pop(ctx, ImageSource.gallery)),
            const SizedBox(height: 4),
            TextButton(onPressed: () => Navigator.pop(ctx),
                child: const Text('Batal', style: TextStyle(color: _t2))),
          ]),
        ),
      ),
    );
  }

  Widget _srcBtn(IconData icon, String label, Color c, Color dim, VoidCallback fn) {
    return Material(color: dim, borderRadius: BorderRadius.circular(11),
      child: InkWell(onTap: fn, borderRadius: BorderRadius.circular(11),
        child: Container(width: double.infinity,
          padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 16),
          decoration: BoxDecoration(borderRadius: BorderRadius.circular(11),
              border: Border.all(color: c.withOpacity(0.25))),
          child: Row(children: [
            Icon(icon, color: c, size: 18), const SizedBox(width: 10),
            Text(label, style: TextStyle(color: c,
                fontWeight: FontWeight.w600, fontSize: 14)),
          ]),
        ),
      ),
    );
  }

  Future<Map<String, dynamic>?> _showStatusDialog(String title) {
    String? selected;
    final ketCtrl = TextEditingController();
    final isIn    = title.contains('Masuk');

    return showDialog<Map<String, dynamic>>(
      context: context,
      builder: (ctx) => StatefulBuilder(builder: (ctx, setSt) {
        return Dialog(
          backgroundColor: _bg1,
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(20),
              side: const BorderSide(color: _line2)),
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(22),
            child: Column(mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start, children: [
              Row(children: [
                Container(width: 42, height: 42,
                    decoration: BoxDecoration(
                        color: isIn ? _greenDim : _roseDim,
                        borderRadius: BorderRadius.circular(11),
                        border: Border.all(
                            color: (isIn ? _green : _rose).withOpacity(0.3))),
                    child: Icon(
                        isIn ? Icons.login_rounded : Icons.logout_rounded,
                        color: isIn ? _green : _rose, size: 20)),
                const SizedBox(width: 12),
                Text(title, style: const TextStyle(
                    fontSize: 16, fontWeight: FontWeight.w700, color: _t1)),
                const Spacer(),
                GestureDetector(onTap: () => Navigator.pop(ctx),
                    child: const Icon(Icons.close_rounded, color: _t3, size: 20)),
              ]),
              const SizedBox(height: 18),
              const Text('PILIH STATUS', style: TextStyle(
                  fontSize: 10, fontWeight: FontWeight.w700,
                  color: _t3, letterSpacing: 1.3)),
              const SizedBox(height: 10),
              ..._statusOptions.map((opt) {
                final isSel = selected == opt['value'];
                final Color c = opt['color'] as Color;
                return GestureDetector(
                  onTap: () => setSt(() {
                    selected = opt['value'] as String;
                    if (selected != 'izin') ketCtrl.clear();
                  }),
                  child: AnimatedContainer(
                    duration: const Duration(milliseconds: 150),
                    margin: const EdgeInsets.only(bottom: 8),
                    padding: const EdgeInsets.symmetric(
                        horizontal: 14, vertical: 11),
                    decoration: BoxDecoration(
                        color: isSel ? c.withOpacity(0.08) : _bg2,
                        borderRadius: BorderRadius.circular(11),
                        border: Border.all(
                            color: isSel ? c.withOpacity(0.45) : _line2,
                            width: isSel ? 1.5 : 1)),
                    child: Row(children: [
                      Icon(opt['icon'] as IconData,
                          color: isSel ? c : _t3, size: 19),
                      const SizedBox(width: 11),
                      Text(opt['label'] as String, style: TextStyle(
                          color: isSel ? c : _t2, fontSize: 14,
                          fontWeight: isSel
                              ? FontWeight.w700 : FontWeight.w400)),
                      const Spacer(),
                      if (isSel)
                        Container(width: 17, height: 17,
                            decoration: BoxDecoration(
                                color: c, shape: BoxShape.circle),
                            child: const Icon(Icons.check,
                                color: Colors.black, size: 11)),
                    ]),
                  ),
                );
              }).toList(),
              if (selected == 'izin') ...[
                const SizedBox(height: 12),
                const Text('KETERANGAN IZIN', style: TextStyle(
                    fontSize: 10, fontWeight: FontWeight.w700,
                    color: _t3, letterSpacing: 1.3)),
                const SizedBox(height: 8),
                TextField(
                  controller: ketCtrl, maxLines: 3,
                  style: const TextStyle(color: _t1, fontSize: 13),
                  cursorColor: _amber,
                  decoration: InputDecoration(
                    hintText: 'Tulis alasan izin...',
                    hintStyle: const TextStyle(color: _t3, fontSize: 13),
                    filled: true, fillColor: _bg2,
                    contentPadding: const EdgeInsets.all(12),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(11),
                        borderSide: BorderSide.none),
                    enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(11),
                        borderSide: const BorderSide(color: _line2)),
                    focusedBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(11),
                        borderSide:
                            const BorderSide(color: _amber, width: 1.5)),
                  ),
                ),
              ],
              const SizedBox(height: 12),
              Container(
                padding: const EdgeInsets.symmetric(
                    horizontal: 11, vertical: 9),
                decoration: BoxDecoration(
                    color: _bg2, borderRadius: BorderRadius.circular(9),
                    border: Border.all(color: _line2)),
                child: Row(children: [
                  Icon(Icons.info_outline_rounded, size: 14,
                      color: selected == 'hadir' ? _green : _t3),
                  const SizedBox(width: 7),
                  Expanded(child: Text(
                    selected == 'hadir'
                        ? 'Foto akan diminta setelah ini'
                        : 'Foto tidak diperlukan untuk status ini',
                    style: TextStyle(fontSize: 12,
                        color: selected == 'hadir' ? _green : _t3),
                  )),
                ]),
              ),
              const SizedBox(height: 18),
              Row(children: [
                Expanded(child: OutlinedButton(
                  onPressed: () => Navigator.pop(ctx),
                  style: OutlinedButton.styleFrom(
                      foregroundColor: _t2,
                      side: const BorderSide(color: _line2),
                      padding: const EdgeInsets.symmetric(vertical: 13),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(11))),
                  child: const Text('Batal'),
                )),
                const SizedBox(width: 10),
                Expanded(flex: 2, child: AnimatedContainer(
                  duration: const Duration(milliseconds: 150),
                  decoration: BoxDecoration(
                      color: selected != null
                          ? (isIn ? _green : _rose) : _bg2,
                      borderRadius: BorderRadius.circular(11),
                      boxShadow: selected != null ? [BoxShadow(
                          color: (isIn ? _green : _rose).withOpacity(0.28),
                          blurRadius: 12,
                          offset: const Offset(0, 4))] : []),
                  child: Material(color: Colors.transparent, child: InkWell(
                    borderRadius: BorderRadius.circular(11),
                    onTap: selected == null ? null : () {
                      if (selected == 'izin' &&
                          ketCtrl.text.trim().isEmpty) {
                        _toast('Keterangan izin harus diisi', ok: false);
                        return;
                      }
                      Navigator.pop(ctx, {
                        'status': selected,
                        'keterangan': selected == 'izin'
                            ? ketCtrl.text.trim() : null,
                      });
                    },
                    child: Padding(
                      padding: const EdgeInsets.symmetric(vertical: 13),
                      child: Text('Lanjutkan',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              fontWeight: FontWeight.w700,
                              fontSize: 14,
                              color: selected != null
                                  ? Colors.black : _t3)),
                    ),
                  )),
                )),
              ]),
            ]),
          ),
        );
      }),
    );
  }

  // ── Helpers ───────────────────────────────────────────────────────────────

  void _toast(String msg, {required bool ok}) {
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Row(children: [
        Icon(ok ? Icons.check_circle_outline : Icons.error_outline,
            color: ok ? _green : _rose, size: 16),
        const SizedBox(width: 8),
        Expanded(child: Text(msg,
            style: const TextStyle(color: _t1, fontSize: 13))),
      ]),
      backgroundColor: _bg1,
      behavior: SnackBarBehavior.floating,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10),
          side: BorderSide(
              color: ok ? _green.withOpacity(0.4) : _rose.withOpacity(0.4))),
      duration: const Duration(seconds: 3),
    ));
  }

  String _formatTime(String? t) {
    if (t == null) return '--:--';
    try {
      final jakarta = tz.getLocation('Asia/Jakarta');
      return DateFormat('HH:mm')
          .format(tz.TZDateTime.from(DateTime.parse(t), jakarta));
    } catch (_) { return t; }
  }

  Color _statusColor(String s) {
    switch (s) {
      case 'hadir': return _green;
      case 'izin':  return _amber;
      case 'sakit': return _rose;
      default:      return _t3;
    }
  }

  Color _statusBg(String s) {
    switch (s) {
      case 'hadir': return _greenDim;
      case 'izin':  return _amberDim;
      case 'sakit': return _roseDim;
      default:      return const Color(0x08ffffff);
    }
  }

  Widget _pill(String text, Color bg, Color fg) => Container(
    padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
    decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(9),
        border: Border.all(color: fg.withOpacity(0.25))),
    child: Text(text, style: TextStyle(
        fontSize: 10, fontWeight: FontWeight.w600, color: fg)),
  );

  Widget _navBtn(IconData icon, VoidCallback onTap) => GestureDetector(
    onTap: onTap,
    child: Container(
      width: 34, height: 34,
      decoration: BoxDecoration(color: _bg2,
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: _line2)),
      child: Icon(icon, color: _t2, size: 18),
    ),
  );

  String _fmtBulan(DateTime d) =>
      DateFormat('MMMM yyyy', 'id_ID').format(d);

  // ═══════════════════════════════════════════════════════════════════════════
  //  BUILD
  // ═══════════════════════════════════════════════════════════════════════════

  @override
  Widget build(BuildContext context) {
    final nama     = (_userData?['teknisi']?['nama_teknisi'] ?? 'Teknisi') as String;
    final id       = _userData?['teknisi']?['id_teknisi'] ?? '-';
    final sudahIn  = _statusAbsensi?['sudah_absen_masuk']  ?? false;
    final sudahOut = _statusAbsensi?['sudah_absen_keluar'] ?? false;
    final data     = _statusAbsensi?['data_absensi'];
    final initial  = nama.isNotEmpty ? nama[0].toUpperCase() : 'T';

    return Scaffold(
      backgroundColor: _bg,
      appBar: _buildAppBar(),
      body: _isLoading
          ? const Center(child: Column(mainAxisSize: MainAxisSize.min, children: [
              SizedBox(width: 36, height: 36,
                  child: CircularProgressIndicator(
                      color: _green, strokeWidth: 2.5)),
              SizedBox(height: 14),
              Text('Memuat data…',
                  style: TextStyle(color: _t2, fontSize: 13)),
            ]))
          : Column(children: [
              // Tab bar
              Container(
                color: _bg1,
                child: TabBar(
                  controller: _tabCtrl,
                  indicatorColor: _green,
                  indicatorWeight: 3,
                  labelColor: _green,
                  unselectedLabelColor: _t3,
                  labelStyle: const TextStyle(
                      fontSize: 13,
                      fontWeight: FontWeight.w800,
                      letterSpacing: 0.5),
                  unselectedLabelStyle: const TextStyle(
                      fontSize: 13, fontWeight: FontWeight.w600),
                  tabs: const [
                    Tab(text: 'ABSEN'),
                    Tab(text: 'REKAP'),
                  ],
                ),
              ),
              const Divider(height: 1, color: _line2),
              Expanded(
                child: TabBarView(
                  controller: _tabCtrl,
                  children: [
                    _buildTabAbsen(
                        initial, nama, id, sudahIn, sudahOut, data),
                    _buildTabRekap(),
                  ],
                ),
              ),
            ]),
    );
  }

  PreferredSizeWidget _buildAppBar() {
    return AppBar(
      elevation: 0,
      backgroundColor: _bg1,
      surfaceTintColor: Colors.transparent,
      systemOverlayStyle: const SystemUiOverlayStyle(
          statusBarColor: Colors.transparent,
          statusBarIconBrightness: Brightness.light),
      title: const Text('Absensi Teknisi', style: TextStyle(
          fontSize: 16, fontWeight: FontWeight.w800, color: _t1, letterSpacing: 0.2)),
      actions: [
        IconButton(
          icon: const Icon(Icons.refresh_rounded, color: _t2, size: 22),
          onPressed: _loadData,
        ),
        const SizedBox(width: 8),
      ],
    );
  }

  // ═══════════════════════════════════════════════════════════════════════════
  //  TAB 1 — ABSEN
  // ═══════════════════════════════════════════════════════════════════════════

  Widget _buildTabAbsen(String initial, String nama, dynamic id,
      bool sudahIn, bool sudahOut, Map<String, dynamic>? data) {
    final now     = DateTime.now();
    final timeStr = DateFormat('HH:mm').format(now);
    final dateStr = DateFormat('EEEE, d MMMM yyyy', 'id_ID').format(now);
    final jadwal  = _userData?['teknisi']?['jadwal_masuk'] ?? '07:30';
    final jamMasuk  = data != null ? _formatTime(data['jam_masuk'])  : '--:--';
    final jamKeluar = data != null ? _formatTime(data['jam_keluar']) : '--:--';
    final durasi    = data?['durasi_kerja_formatted'] ?? '--';

    return RefreshIndicator(
      onRefresh: _loadData, color: _green, backgroundColor: _bg1,
      child: SingleChildScrollView(
        physics: const AlwaysScrollableScrollPhysics(),
        padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 24),
        child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
          // Greeting & Profile
          Row(children: [
            Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
              Text('Selamat ${now.hour < 11 ? 'Pagi' : now.hour < 15 ? 'Siang' : now.hour < 18 ? 'Sore' : 'Malam'},',
                  style: const TextStyle(color: _t2, fontSize: 13, fontWeight: FontWeight.w500)),
              const SizedBox(height: 2),
              Text(nama, style: const TextStyle(color: _t1, fontSize: 18, fontWeight: FontWeight.w800)),
            ]),
            const Spacer(),
            _pill('ID: $id', _greenDim, _green),
          ]),
          
          const SizedBox(height: 30),

          // Central Clock Display
          Center(
            child: Column(children: [
              Text(timeStr, style: const TextStyle(fontSize: 64, fontWeight: FontWeight.w900, color: _t1, letterSpacing: -2, height: 1)),
              Text(dateStr, style: const TextStyle(color: _t2, fontSize: 14, fontWeight: FontWeight.w500)),
              const SizedBox(height: 12),
            ]),
          ),

          const SizedBox(height: 40),

          // Log Aktivitas Card
          Container(
            padding: const EdgeInsets.all(20),
            decoration: BoxDecoration(
              color: _bg1,
              borderRadius: BorderRadius.circular(24),
              border: Border.all(color: _line2),
              boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 20, offset: const Offset(0, 10))],
            ),
            child: Column(children: [
              Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
                const Text('LOG AKTIVITAS', style: TextStyle(color: _t3, fontSize: 11, fontWeight: FontWeight.w800, letterSpacing: 1.5)),
                if (data != null) 
                  _pill(
                    sudahOut ? 'Selesai' : (data['status'] == 'hadir' ? 'Sedang Bekerja' : data['status'].toUpperCase()), 
                    sudahOut ? _greenDim : (data['status'] == 'hadir' ? _cyanDim : _roseDim), 
                    sudahOut ? _green : (data['status'] == 'hadir' ? _cyan : _rose)
                  ),
              ]),
              const SizedBox(height: 20),
              
              Row(children: [
                _logItem('JADWAL', jadwal, Icons.alarm_rounded, _cyan),
                _vLine(),
                _logItem('MASUK', jamMasuk, Icons.login_rounded, sudahIn ? _green : _t3),
              ]),
              const Padding(padding: EdgeInsets.symmetric(vertical: 15), child: Divider(color: _line2, height: 1)),
              Row(children: [
                _logItem('KELUAR', jamKeluar, Icons.logout_rounded, sudahOut ? _rose : _t3),
                _vLine(),
                _logItem('DURASI', durasi, Icons.timer_outlined, _amber),
              ]),
            ]),
          ),

          const SizedBox(height: 32),

          // Floating Action Area
          _buildActionArea(sudahIn, sudahOut, data),
        ]),
      ),
    );
  }

  Widget _logItem(String label, String value, IconData icon, Color color) {
    return Expanded(
      child: Row(children: [
        Container(
          padding: const EdgeInsets.all(8),
          decoration: BoxDecoration(color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(10)),
          child: Icon(icon, color: color, size: 18),
        ),
        const SizedBox(width: 12),
        Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Text(label, style: const TextStyle(color: _t3, fontSize: 9, fontWeight: FontWeight.w700)),
          const SizedBox(height: 2),
          Text(value, style: TextStyle(color: color == _t3 ? _t3 : _t1, fontSize: 16, fontWeight: FontWeight.w800)),
        ]),
      ]),
    );
  }

  Widget _vLine() => Container(width: 1, height: 30, color: _line2, margin: const EdgeInsets.symmetric(horizontal: 10));

  Widget _buildActionArea(bool sudahIn, bool sudahOut, Map<String, dynamic>? data) {
    if (sudahIn && sudahOut) {
      return Container(
        padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
        decoration: BoxDecoration(color: _greenDim, borderRadius: BorderRadius.circular(16), border: Border.all(color: _green.withOpacity(0.2))),
        child: const Row(mainAxisAlignment: MainAxisAlignment.center, children: [
          Icon(Icons.check_circle_rounded, color: _green, size: 20),
          const SizedBox(width: 10),
          Text('Kerja hari ini selesai', style: TextStyle(color: _green, fontWeight: FontWeight.w700, fontSize: 14)),
        ]),
      );
    }

    if (data != null && (data['status'] == 'izin' || data['status'] == 'sakit')) {
      final Color c = data['status'] == 'sakit' ? _rose : _amber;
      return Container(
        padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
        decoration: BoxDecoration(color: c.withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all(color: c.withOpacity(0.2))),
        child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
          Icon(data['status'] == 'sakit' ? Icons.local_hospital_rounded : Icons.event_busy_rounded, color: c, size: 20),
          const SizedBox(width: 10),
          Text('Status: ${data['status'].toUpperCase()}', style: TextStyle(color: c, fontWeight: FontWeight.w700, fontSize: 14)),
        ]),
      );
    }

    final String label = !sudahIn ? 'Absen Masuk' : 'Absen Keluar';
    final Color color  = !sudahIn ? _green : _rose;
    final IconData ico = !sudahIn ? Icons.fingerprint_rounded : Icons.logout_rounded;
    final VoidCallback fn = !sudahIn ? _handleAbsenMasuk : _handleAbsenKeluar;

    return Container(
      height: 64,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        gradient: LinearGradient(colors: [color, color.withBlue(150)], begin: Alignment.topLeft, end: Alignment.bottomRight),
        boxShadow: [BoxShadow(color: color.withOpacity(0.3), blurRadius: 20, offset: const Offset(0, 8))],
      ),
      child: Material(
        color: Colors.transparent,
        child: InkWell(
          borderRadius: BorderRadius.circular(20),
          onTap: _isProcessing ? null : fn,
          child: Center(
            child: _isProcessing
              ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(color: Colors.black, strokeWidth: 3))
              : Row(mainAxisAlignment: MainAxisAlignment.center, children: [
                  Icon(ico, color: Colors.black, size: 24),
                  const SizedBox(width: 12),
                  Text(label.toUpperCase(), style: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w900, letterSpacing: 1)),
                ]),
          ),
        ),
      ),
    );
  }

  // ═══════════════════════════════════════════════════════════════════════════
  //  TAB 2 — REKAP & RIWAYAT
  // ═══════════════════════════════════════════════════════════════════════════

  Widget _buildTabRekap() {
    return _isLoadingRekap
        ? const Center(child: CircularProgressIndicator(color: _green, strokeWidth: 2.5))
        : _rekap.isEmpty
            ? Center(child: Column(mainAxisSize: MainAxisSize.min, children: [
                Container(width: 56, height: 56,
                    decoration: BoxDecoration(color: _bg2, borderRadius: BorderRadius.circular(14), border: Border.all(color: _line2)),
                    child: const Icon(Icons.bar_chart_rounded, color: _t3, size: 26)),
                const SizedBox(height: 14),
                const Text('Tidak ada data rekap', style: TextStyle(color: _t2, fontSize: 14)),
                const SizedBox(height: 8),
                GestureDetector(
                  onTap: () { _fetchRekap(); _fetchRiwayat(); },
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                    decoration: BoxDecoration(color: _greenDim, borderRadius: BorderRadius.circular(8), border: Border.all(color: _green.withOpacity(0.3))),
                    child: const Text('Muat Rekap', style: TextStyle(color: _green, fontSize: 12, fontWeight: FontWeight.w600)),
                  ),
                ),
              ]))
            : _buildRekapContent();
  }

  Widget _buildRekapContent() {
    final pct   = (_rekap['persentase'] as num?)?.toDouble() ?? 0.0;
    final hadir = (_rekap['hadir']  as num?)?.toInt() ?? 0;
    final izin  = (_rekap['izin']   as num?)?.toInt() ?? 0;
    final sakit = (_rekap['sakit']  as num?)?.toInt() ?? 0;
    final alpha = (_rekap['alpha']  as num?)?.toInt() ?? 0;
    final total = (_rekap['total_hari_kerja'] as num?)?.toInt() ?? 1;

    return CustomScrollView(
      slivers: [
        SliverToBoxAdapter(
          child: Padding(
            padding: const EdgeInsets.fromLTRB(20, 24, 20, 16),
            child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
              // Bulan nav
              Row(children: [
                Text(_rekap['bulan']?.toString() ?? _fmtBulan(_bulanRekap),
                    style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w800, color: _t1)),
                const Spacer(),
                _navBtn(Icons.chevron_left_rounded, () {
                  setState(() {
                    _bulanRekap = DateTime(_bulanRekap.year, _bulanRekap.month - 1);
                    _rekap = {}; _riwayat = [];
                  });
                  _fetchRekap(); _fetchRiwayat();
                }),
                const SizedBox(width: 8),
                _navBtn(Icons.chevron_right_rounded, () {
                  setState(() {
                    _bulanRekap = DateTime(_bulanRekap.year, _bulanRekap.month + 1);
                    _rekap = {}; _riwayat = [];
                  });
                  _fetchRekap(); _fetchRiwayat();
                }),
              ]),
              const SizedBox(height: 20),

              // Calendar Grid
              _buildCalendarGrid(),
              
              const SizedBox(height: 24),

              const SizedBox(height: 16),

              // 3 Stats Grid
              Row(children: [
                Expanded(child: _rekapStatCard('$hadir', 'Hadir', _green, hadir/total)),
                const SizedBox(width: 10),
                Expanded(child: _rekapStatCard('$izin', 'Izin', _amber, izin/total)),
                const SizedBox(width: 10),
                Expanded(child: _rekapStatCard('$sakit', 'Sakit', _rose, sakit/total)),
              ]),

              const SizedBox(height: 32),
              const Text('RIWAYAT HARIAN', style: TextStyle(fontSize: 11, color: _t3, fontWeight: FontWeight.w800, letterSpacing: 1.5)),
              const SizedBox(height: 16),
            ]),
          ),
        ),

        // Riwayat List
        if (_isLoadingRiwayat)
          const SliverFillRemaining(child: Center(child: CircularProgressIndicator(color: _green)))
        else if (_riwayat.isEmpty)
          const SliverToBoxAdapter(
            child: Center(
              child: Padding(
                padding: EdgeInsets.symmetric(vertical: 40),
                child: Text('Tidak ada riwayat bulan ini', style: TextStyle(color: _t3)),
              ),
            ),
          )
        else
          SliverPadding(
            padding: const EdgeInsets.fromLTRB(20, 0, 20, 40),
            sliver: SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, i) => _buildHistoryItem(_riwayat[i]),
                childCount: _riwayat.length,
              ),
            ),
          ),
      ],
    );
  }

  Widget _rekapStatCard(String val, String label, Color color, double frac) {
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 4),
      decoration: BoxDecoration(color: _bg1, borderRadius: BorderRadius.circular(16), border: Border.all(color: color.withOpacity(0.15))),
      child: Column(children: [
        Text(val, style: TextStyle(fontSize: 22, fontWeight: FontWeight.w900, color: color)),
        const SizedBox(height: 2),
        Text(label, style: const TextStyle(fontSize: 9, color: _t2, fontWeight: FontWeight.w700)),
        const SizedBox(height: 10),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 12),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(100),
            child: LinearProgressIndicator(value: frac.clamp(0.0, 1.0), minHeight: 2, backgroundColor: color.withOpacity(0.1), valueColor: AlwaysStoppedAnimation(color)),
          ),
        ),
      ]),
    );
  }

  Widget _buildHistoryItem(Map<String, dynamic> item) {
    final status  = (item['status'] ?? 'alpha') as String;
    final color   = _statusColor(status);
    final bg      = _statusBg(status);
    final masuk   = item['jam_masuk_formatted']  as String?;
    final keluar  = item['jam_keluar_formatted'] as String?;
    final tanggal = item['tanggal'] as String? ?? '';
    final dayNum  = tanggal.length >= 10 ? tanggal.substring(8, 10) : '--';
    final dayName = tanggal.isNotEmpty ? DateFormat('EEEE', 'id_ID').format(DateTime.parse(tanggal)) : '-';

    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(color: _bg1, borderRadius: BorderRadius.circular(16), border: Border.all(color: _line2)),
      child: Row(children: [
        Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          Text(dayNum, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w900, color: _t1)),
          Text(dayName.substring(0, 3).toUpperCase(), style: const TextStyle(fontSize: 10, color: _t3, fontWeight: FontWeight.w800)),
        ]),
        const SizedBox(width: 20),
        Container(width: 1, height: 30, color: _line2),
        const SizedBox(width: 20),
        Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
          if (status == 'libur')
            const Text('Hari Libur', style: TextStyle(fontSize: 14, color: _t3, fontStyle: FontStyle.italic))
          else
            Row(children: [
              Text(masuk ?? '--:--', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w800, color: masuk != null ? _t1 : _t3)),
              const Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: Text('→', style: TextStyle(color: _t3))),
              Text(keluar ?? '--:--', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w800, color: keluar != null ? _t1 : _t3)),
            ]),
          const SizedBox(height: 2),
          Text(status == 'hadir' ? (keluar != null ? 'Selesai' : 'Sedang Bekerja') : status.toUpperCase(),
              style: TextStyle(fontSize: 10, color: color, fontWeight: FontWeight.w700)),
        ])),
        Container(
          padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
          decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(100), border: Border.all(color: color.withOpacity(0.2))),
          child: Text(status.toUpperCase(), style: TextStyle(fontSize: 9, fontWeight: FontWeight.w900, color: color)),
        ),
      ]),
    );
  }
  Widget _buildCalendarGrid() {
    final daysInMonth = DateTime(_bulanRekap.year, _bulanRekap.month + 1, 0).day;
    final firstDay = DateTime(_bulanRekap.year, _bulanRekap.month, 1).weekday;
    
    // Day labels
    const weekDays = ['Sn', 'Sl', 'Rb', 'Km', 'Jm', 'Sb', 'Mg'];

    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: _bg1,
        borderRadius: BorderRadius.circular(20),
        border: Border.all(color: _line2),
      ),
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: weekDays.map((d) => Text(d, style: const TextStyle(color: _t3, fontSize: 11, fontWeight: FontWeight.w800))).toList(),
          ),
          const SizedBox(height: 12),
          GridView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 7,
              mainAxisSpacing: 8,
              crossAxisSpacing: 8,
            ),
            itemCount: daysInMonth + (firstDay - 1),
            itemBuilder: (context, index) {
              if (index < firstDay - 1) return const SizedBox();
              
              final day = index - (firstDay - 2);
              final status = _kalenderData[day];
              
              Color dotColor = Colors.transparent;
              Color textColor = _t2;
              BoxDecoration? deco;

              if (status != null) {
                dotColor = _statusColor(status);
                textColor = _t1;
                deco = BoxDecoration(
                  color: _statusBg(status),
                  shape: BoxShape.circle,
                  border: Border.all(color: dotColor.withOpacity(0.3)),
                );
              }

              return Center(
                child: Container(
                  width: 32,
                  height: 32,
                  decoration: deco,
                  child: Center(
                    child: Text('$day', 
                      style: TextStyle(
                        color: textColor, 
                        fontSize: 12, 
                        fontWeight: status != null ? FontWeight.w900 : FontWeight.w400
                      )
                    ),
                  ),
                ),
              );
            },
          ),
          const SizedBox(height: 16),
          // Legend
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              _legendItem('Masuk', _green),
              const SizedBox(width: 12),
              _legendItem('Izin', _amber),
              const SizedBox(width: 12),
              _legendItem('Sakit', _rose),
              const SizedBox(width: 12),
              _legendItem('Alfa', _t3),
            ],
          )
        ],
      ),
    );
  }

  Widget _legendItem(String label, Color color) {
    return Row(
      children: [
        Container(width: 6, height: 6, decoration: BoxDecoration(color: color, shape: BoxShape.circle)),
        const SizedBox(width: 4),
        Text(label, style: const TextStyle(color: _t3, fontSize: 9, fontWeight: FontWeight.w700)),
      ],
    );
  }
}