import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:laki_icu_app/blocs/device_control/device_control_bloc.dart';
import 'package:laki_icu_app/blocs/device_control/device_control_event.dart';
import 'package:laki_icu_app/blocs/device_control/device_control_state.dart';
import 'package:laki_icu_app/models/bo/monitoring_bo.dart';
import 'package:laki_icu_app/utils/numeric_keyboard.dart';

import 'device_control_common.dart';

/// 环境指标控制卡片（温度/湿度/氧气/二氧化碳）
class DeviceControlMetricCard extends StatelessWidget {
  const DeviceControlMetricCard({super.key, required this.metric});

  final MonitoringMetricBO metric;

  @override
  Widget build(BuildContext context) {
    final isTemperature = metric.label.contains('温度');
    final isHumidity = metric.label.contains('湿度');
    final isOxygen = metric.label.contains('氧气');
    final isCo2 = metric.label.contains('二氧化碳') ||
        metric.label.toUpperCase().contains('CO');

    return BlocBuilder<DeviceControlBloc, DeviceControlState>(
      buildWhen: (previous, current) =>
          previous.data.cabinTemp.setValue != current.data.cabinTemp.setValue ||
          previous.data.cabinHumidity.setValue !=
              current.data.cabinHumidity.setValue ||
          previous.data.oxygenConcentration.setValue !=
              current.data.oxygenConcentration.setValue ||
          previous.data.co2Concentration.alarmThreshold !=
              current.data.co2Concentration.alarmThreshold ||
          previous.data.cabinTemp.currentValue !=
              current.data.cabinTemp.currentValue ||
          previous.data.cabinHumidity.currentValue !=
              current.data.cabinHumidity.currentValue ||
          previous.data.oxygenConcentration.currentValue !=
              current.data.oxygenConcentration.currentValue ||
          previous.data.co2Concentration.currentValue !=
              current.data.co2Concentration.currentValue,
      builder: (context, state) {
        final currentValue = isTemperature
            ? state.data.cabinTemp.currentValue
            : isCo2
                ? state.data.co2Concentration.currentValue
                : isOxygen
                    ? state.data.oxygenConcentration.currentValue
                    : isHumidity
                        ? state.data.cabinHumidity.currentValue
                        : metric.value;
        final setValue = isTemperature
            ? state.data.cabinTemp.setValue
            : isCo2
                ? state.data.co2Concentration.alarmThreshold
                : isOxygen
                    ? state.data.oxygenConcentration.setValue
                    : isHumidity
                        ? state.data.cabinHumidity.setValue
                        : '24';
        final adjustEventBuilder = _adjustEventBuilder(
          isTemperature: isTemperature,
          isHumidity: isHumidity,
          isOxygen: isOxygen,
          isCo2: isCo2,
        );
        final setValueEventBuilder = _setValueEventBuilder(
          isTemperature: isTemperature,
          isHumidity: isHumidity,
          isOxygen: isOxygen,
          isCo2: isCo2,
        );

        return DeviceControlPanelFrame(
          active: isOxygen,
          backgroundAsset: isOxygen ? assetMetricGreen : assetMetricBlue,
          padding: EdgeInsets.fromLTRB(32.w, 26.h, 32.w, 28.h),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  Expanded(
                    child: DeviceControlPanelTitle(_title(metric.label)),
                  ),
                  DeviceControlPill(
                    text: isOxygen
                        ? 'ON'
                        : isCo2
                            ? 'PPM'
                            : 'Off',
                    active: isOxygen,
                  ),
                ],
              ),
              const Spacer(),
              Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(
                    currentValue,
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: isCo2 ? 60.sp : 82.sp,
                      height: 0.9,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  SizedBox(width: 12.w),
                  Padding(
                    padding: EdgeInsets.only(bottom: 8.h),
                    child: Text(
                      isCo2 ? '' : metric.unit,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 28.sp,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                  const Spacer(),
                  Image.asset(
                    deviceControlIconAsset(metric.label),
                    width: 72.w,
                    height: 72.w,
                    fit: BoxFit.contain,
                  ),
                ],
              ),
              Divider(
                  color: Colors.white.withValues(alpha: 0.18), height: 28.h),
              Text(
                isCo2
                    ? '告警阈值设定'
                    : metric.label.contains('温度')
                        ? '温度设定'
                        : '湿度设定',
                style: TextStyle(
                  color: Colors.white.withValues(alpha: 0.78),
                  fontSize: 26.sp,
                ),
              ),
              const Spacer(),
              Row(
                children: [
                  _MetricAdjustButton(
                    text: '-',
                    active: adjustEventBuilder != null,
                    onTap: adjustEventBuilder == null
                        ? null
                        : () => context.read<DeviceControlBloc>().add(
                              adjustEventBuilder(false),
                            ),
                  ),
                  const Spacer(),
                  GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    onTap: setValueEventBuilder == null
                        ? null
                        : () => _showSetValueKeyboard(
                              context,
                              initialValue: setValue,
                              decimalEnabled: isTemperature,
                              eventBuilder: setValueEventBuilder,
                            ),
                    child: Padding(
                      padding:
                          EdgeInsets.symmetric(horizontal: 18.w, vertical: 8.h),
                      child: Text(
                        setValue,
                        style: TextStyle(
                          color: isCo2
                              ? const Color(0xFFFFC400)
                              : const Color(0xFF00B7F4),
                          fontSize: 64.sp,
                          height: 1,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  ),
                  const Spacer(),
                  _MetricAdjustButton(
                    text: '+',
                    active: adjustEventBuilder != null,
                    onTap: adjustEventBuilder == null
                        ? null
                        : () => context.read<DeviceControlBloc>().add(
                              adjustEventBuilder(true),
                            ),
                  ),
                ],
              ),
            ],
          ),
        );
      },
    );
  }

  static String _title(String label) {
    if (label.contains('二氧化碳')) return '二氧化碳浓度';
    return label;
  }

  static DeviceControlEvent Function(bool increase)? _adjustEventBuilder({
    required bool isTemperature,
    required bool isHumidity,
    required bool isOxygen,
    required bool isCo2,
  }) {
    if (isTemperature) {
      return (increase) =>
          DeviceControlCabinTempSetValueAdjusted(increase ? 1 : -1);
    }
    if (isHumidity) {
      return (increase) =>
          DeviceControlCabinHumiditySetValueAdjusted(increase ? 1 : -1);
    }
    if (isOxygen) {
      return (increase) =>
          DeviceControlOxygenConcentrationSetValueAdjusted(increase ? 1 : -1);
    }
    if (isCo2) {
      return (increase) => DeviceControlCO2ConcentrationAlarmThresholdAdjusted(
          increase ? 100 : -100);
    }
    return null;
  }

  static DeviceControlEvent Function(String value)? _setValueEventBuilder({
    required bool isTemperature,
    required bool isHumidity,
    required bool isOxygen,
    required bool isCo2,
  }) {
    if (isTemperature) {
      return (value) => DeviceControlCabinTempSetValueChanged(value);
    }
    if (isHumidity) {
      return (value) => DeviceControlCabinHumiditySetValueChanged(value);
    }
    if (isOxygen) {
      return (value) => DeviceControlOxygenConcentrationSetValueChanged(value);
    }
    if (isCo2) {
      return (value) =>
          DeviceControlCO2ConcentrationAlarmThresholdChanged(value);
    }
    return null;
  }

  static Future<void> _showSetValueKeyboard(
    BuildContext context, {
    required String initialValue,
    required bool decimalEnabled,
    required DeviceControlEvent Function(String value) eventBuilder,
  }) async {
    final result = await NumericKeyboard.show(
      context,
      initialValue: initialValue == '--' ? '' : initialValue,
      decimalEnabled: decimalEnabled,
    );
    if (!context.mounted || result == null) return;

    final value = result.trim();
    if (value.isEmpty || value == '.') return;
    context.read<DeviceControlBloc>().add(eventBuilder(value));
  }
}

class _MetricAdjustButton extends StatelessWidget {
  const _MetricAdjustButton({
    required this.text,
    required this.active,
    this.onTap,
  });

  final String text;
  final bool active;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: onTap,
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
        child: DeviceControlAdjustText(text, active: active),
      ),
    );
  }
}
