import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'overtime_model.dart';
import 'overtime_api.dart';

class OvertimeApplyState {
  final OvertimeModel overtime;
  final bool isSubmitting;
  const OvertimeApplyState({required this.overtime, this.isSubmitting = false});
  OvertimeApplyState copyWith({OvertimeModel? overtime, bool? isSubmitting}) =>
      OvertimeApplyState(
        overtime: overtime ?? this.overtime,
        isSubmitting: isSubmitting ?? this.isSubmitting,
      );
}

class OvertimeApplyController extends StateNotifier<OvertimeApplyState> {
  final OvertimeApi _api;
  OvertimeApplyController(this._api)
    : super(
        OvertimeApplyState(
          overtime: OvertimeModel(
            id: '',
            applicationNo: '',
            applicantId: '',
            applicantName: '',
            deptId: '',
            deptName: '',
            otDate: DateTime.now(),
            startTime: DateTime.now(),
            endTime: DateTime.now().add(const Duration(hours: 2)),
            otHours: 2.0,
            otType: '工作日加班',
            compensationType: '加班费',
            reason: '',
            createTime: DateTime.now(),
            updateTime: DateTime.now(),
          ),
        ),
      );

  void updateOtDate(DateTime d) =>
      state = state.copyWith(overtime: state.overtime.copyWith(otDate: d));
  void updateType(String t) =>
      state = state.copyWith(overtime: state.overtime.copyWith(otType: t));
  void updateCompensation(String c) => state = state.copyWith(
    overtime: state.overtime.copyWith(compensationType: c),
  );
  void updateStartTime(DateTime t) {
    state = state.copyWith(overtime: state.overtime.copyWith(startTime: t));
    _recalc();
  }

  void updateEndTime(DateTime t) {
    state = state.copyWith(overtime: state.overtime.copyWith(endTime: t));
    _recalc();
  }

  void updateReason(String r) =>
      state = state.copyWith(overtime: state.overtime.copyWith(reason: r));
  void _recalc() {
    final d =
        state.overtime.endTime.difference(state.overtime.startTime).inMinutes /
        60.0;
    state = state.copyWith(overtime: state.overtime.copyWith(otHours: d));
  }

  Future<bool> submit() async {
    state = state.copyWith(isSubmitting: true);
    try {
      await _api.submit(state.overtime.copyWith(status: 'pending'));
      return true;
    } catch (_) {
      return false;
    } finally {
      state = state.copyWith(isSubmitting: false);
    }
  }

  Future<bool> saveDraft() async {
    state = state.copyWith(isSubmitting: true);
    try {
      await _api.saveDraft(state.overtime);
      return true;
    } catch (_) {
      return false;
    } finally {
      state = state.copyWith(isSubmitting: false);
    }
  }
}

final overtimeApplyProvider = StateNotifierProvider.autoDispose
    .family<OvertimeApplyController, OvertimeApplyState, String?>((
      ref,
      editId,
    ) {
      return OvertimeApplyController(ref.read(overtimeApiProvider));
    });
