import 'package:core_localization/core_localization.dart';
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:firebase_data_connect/firebase_data_connect.dart' as fdc;
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'coverage_dashboard.dart';

/// A widget that displays live activity information.
class LiveActivityWidget extends StatefulWidget {

  /// Creates a [LiveActivityWidget].
  const LiveActivityWidget({
    super.key,
    required this.onViewAllPressed,
    this.subtitle
  });
  /// Callback when "View all" is pressed.
  final VoidCallback onViewAllPressed;

  /// Optional subtitle for the section.
  final String? subtitle;

  @override
  State<LiveActivityWidget> createState() => _LiveActivityWidgetState();
}

class _LiveActivityWidgetState extends State<LiveActivityWidget> {
  late final Future<_LiveActivityData> _liveActivityFuture =
      _loadLiveActivity();

  Future<_LiveActivityData> _loadLiveActivity() async {
    final String? businessId =
        dc.ClientSessionStore.instance.session?.business?.id;
    if (businessId == null || businessId.isEmpty) {
      return _LiveActivityData.empty();
    }

    final DateTime now = DateTime.now();
    final DateTime start = DateTime(now.year, now.month, now.day);
    final DateTime end = DateTime(now.year, now.month, now.day, 23, 59, 59, 999);
    final fdc.QueryResult<dc.ListShiftRolesByBusinessAndDateRangeData,
        dc.ListShiftRolesByBusinessAndDateRangeVariables> shiftRolesResult =
        await dc.ExampleConnector.instance
            .listShiftRolesByBusinessAndDateRange(
              businessId: businessId,
              start: _toTimestamp(start),
              end: _toTimestamp(end),
            )
            .execute();
    final fdc.QueryResult<dc.ListStaffsApplicationsByBusinessForDayData,
        dc.ListStaffsApplicationsByBusinessForDayVariables> result =
        await dc.ExampleConnector.instance
            .listStaffsApplicationsByBusinessForDay(
              businessId: businessId,
              dayStart: _toTimestamp(start),
              dayEnd: _toTimestamp(end),
            )
            .execute();

    if (shiftRolesResult.data.shiftRoles.isEmpty &&
        result.data.applications.isEmpty) {
      return _LiveActivityData.empty();
    }

    int totalNeeded = 0;
    double totalCost = 0;
    for (final dc.ListShiftRolesByBusinessAndDateRangeShiftRoles shiftRole
        in shiftRolesResult.data.shiftRoles) {
      totalNeeded += shiftRole.count;
      totalCost += shiftRole.totalValue ?? 0;
    }

    final int totalAssigned = result.data.applications.length;
    int lateCount = 0;
    int checkedInCount = 0;
    for (final dc.ListStaffsApplicationsByBusinessForDayApplications app
        in result.data.applications) {
      if (app.checkInTime != null) {
        checkedInCount += 1;
      }
      if (app.status is dc.Known<dc.ApplicationStatus> &&
          (app.status as dc.Known<dc.ApplicationStatus>).value ==
              dc.ApplicationStatus.LATE) {
        lateCount += 1;
      }
    }

    return _LiveActivityData(
      totalNeeded: totalNeeded,
      totalAssigned: totalAssigned,
      totalCost: totalCost,
      checkedInCount: checkedInCount,
      lateCount: lateCount,
    );
  }

  fdc.Timestamp _toTimestamp(DateTime dateTime) {
    final DateTime utc = dateTime.toUtc();
    final int seconds = utc.millisecondsSinceEpoch ~/ 1000;
    final int nanoseconds =
        (utc.millisecondsSinceEpoch % 1000) * 1000000;
    return fdc.Timestamp(nanoseconds, seconds);
  }

  @override
  Widget build(BuildContext context) {
    final TranslationsClientHomeEn i18n = t.client_home;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Text(
              i18n.widgets.live_activity.toUpperCase(),
              style: UiTypography.footnote1b.textSecondary.copyWith(
                letterSpacing: 0.5,
              ),
            ),
            GestureDetector(
              onTap: widget.onViewAllPressed,
              child: Text(
                i18n.dashboard.view_all,
                style: UiTypography.footnote1m.copyWith(
                  color: UiColors.primary,
                ),
              ),
            ),
          ],
        ),
        if (widget.subtitle != null) ...<Widget>[
          Text(
            widget.subtitle!,
            style: UiTypography.body2r.textSecondary,
          ),
        ],
        const SizedBox(height: UiConstants.space6),
        FutureBuilder<_LiveActivityData>(
          future: _liveActivityFuture,
          builder: (BuildContext context,
              AsyncSnapshot<_LiveActivityData> snapshot) {
            final _LiveActivityData data =
                snapshot.data ?? _LiveActivityData.empty();
            final List<Map<String, Object>> shifts =
                <Map<String, Object>>[
              <String, Object>{
                'workersNeeded': data.totalNeeded,
                'filled': data.totalAssigned,
                'hourlyRate': 1.0,
                'hours': data.totalCost,
                'status': 'OPEN',
                'date': DateTime.now().toIso8601String().split('T')[0],
              },
            ];
            final List<Map<String, Object?>> applications =
                <Map<String, Object?>>[];
            for (int i = 0; i < data.checkedInCount; i += 1) {
              applications.add(
                <String, Object?>{
                  'status': 'CONFIRMED',
                  'checkInTime': '09:00',
                },
              );
            }
            for (int i = 0; i < data.lateCount; i += 1) {
              applications.add(<String, Object?>{'status': 'LATE'});
            }
            return CoverageDashboard(
              shifts: shifts,
              applications: applications,
            );
          },
        ),
      ],
    );
  }
}

class _LiveActivityData {

  factory _LiveActivityData.empty() {
    return const _LiveActivityData(
      totalNeeded: 0,
      totalAssigned: 0,
      totalCost: 0,
      checkedInCount: 0,
      lateCount: 0,
    );
  }
  const _LiveActivityData({
    required this.totalNeeded,
    required this.totalAssigned,
    required this.totalCost,
    required this.checkedInCount,
    required this.lateCount,
  });

  final int totalNeeded;
  final int totalAssigned;
  final double totalCost;
  final int checkedInCount;
  final int lateCount;
}
