part of '../../app/app.dart';

class ExpertiseScreen extends StatefulWidget {
  const ExpertiseScreen({
    super.key,
    required this.token,
    required this.baseUrl,
    required this.id,
  });

  final String token;
  final String baseUrl;
  final int id;

  @override
  State<ExpertiseScreen> createState() => _ExpertiseScreenState();
}

class _ExpertiseScreenState extends State<ExpertiseScreen> {
  late final ApiClient _api;
  late Future<Map<String, dynamic>> _future;
  final Map<String, TextEditingController> _textControllers = {};
  final Map<String, String> _selectValues = {};
  final Map<String, Set<String>> _multiValues = {};
  final Map<String, String> _staffValues = {};
  final Map<String, int> _wizardSteps = {};
  String _currentDlp = '';
  bool _criticalValue = false;
  bool _saving = false;

  @override
  void initState() {
    super.initState();
    _api = ApiClient(baseUrl: widget.baseUrl, token: widget.token);
    _future = _load();
  }

  @override
  void dispose() {
    for (final controller in _textControllers.values) {
      controller.dispose();
    }
    super.dispose();
  }

  Future<Map<String, dynamic>> _load() {
    return _api.get('api/mobile/examinations/${widget.id}/expertise');
  }

  void _reload() {
    setState(() {
      _future = _load();
    });
  }

  void _prepareFields(Map<String, dynamic> data) {
    final dlp = data['dlp']?.toString() ?? '';
    if (_currentDlp == dlp && _textControllers.isNotEmpty) {
      return;
    }
    _currentDlp = dlp;
    for (final controller in _textControllers.values) {
      controller.dispose();
    }
    _textControllers.clear();
    _selectValues.clear();
    _multiValues.clear();
    _staffValues.clear();

    final components = asMap(data['components']);
    final item = asMap(data['item']);
    final user = asMap(data['user']);
    _staffValues['analis'] = (item['analis'] ?? user['id'] ?? '0').toString();
    _staffValues['ppds3'] = (item['ppds3'] ?? user['id'] ?? '0').toString();
    _staffValues['dokter'] = (item['dokter_id'] ?? user['id'] ?? '0')
        .toString();
    _criticalValue = data['is_critical'] == true;
    for (final rawField in asList(data['fields'])) {
      final field = asMap(rawField);
      final name = field['name']?.toString() ?? '';
      final type = field['type']?.toString() ?? 'text';
      final value = components[name];
      if (type == 'select') {
        _selectValues[name] = value?.toString() ?? '';
      } else if (type == 'multiselect') {
        _multiValues[name] = value is List
            ? value.map((item) => item.toString()).toSet()
            : <String>{};
      } else {
        _textControllers[name] = TextEditingController(
          text: value?.toString() ?? '',
        );
      }
    }
    for (final name in kAntibioticMediaRowFields) {
      _textControllers[name] = TextEditingController(
        text: components[name]?.toString() ?? '',
      );
    }
    for (final name in kToolAntibioticRowFields) {
      _textControllers[name] = TextEditingController(
        text: components[name]?.toString() ?? '',
      );
    }
  }

  Future<void> _setTemplate(String dlp) async {
    setState(() => _saving = true);
    try {
      await _api.post(
        'api/mobile/examinations/${widget.id}/expertise/template',
        {'dlp': dlp},
      );
      if (!mounted) return;
      _showMessage('Template $dlp dipilih.');
      setState(() {
        _future = _load();
      });
    } on ApiException catch (error) {
      _showMessage(error.message);
    } catch (_) {
      _showMessage('Template tidak bisa dipilih.');
    } finally {
      if (mounted) {
        setState(() => _saving = false);
      }
    }
  }

  Future<void> _save(String action) async {
    if (action == 'statuspewarnaanlsg') {
      _wizardSteps[_currentDlp] = 1;
    }
    setState(() => _saving = true);
    final fields = <String, dynamic>{};
    for (final entry in _textControllers.entries) {
      fields[entry.key] = entry.value.text.trim();
    }
    for (final entry in _selectValues.entries) {
      fields[entry.key] = entry.value;
    }
    for (final entry in _multiValues.entries) {
      fields[entry.key] = entry.value.toList();
    }

    Map<String, dynamic> data;
    try {
      data = await _api.post('api/mobile/examinations/${widget.id}/expertise', {
        'dlp': _currentDlp,
        'action': action,
        'fields': fields,
        'keterangan': fields['keterangan']?.toString() ?? '',
        'analis': _staffValues['analis'] ?? '0',
        'ppds3': _staffValues['ppds3'] ?? '0',
        'dokter': _staffValues['dokter'] ?? '0',
        'nilai_kritis': _criticalValue ? '1' : '0',
      });
    } on ApiException catch (error) {
      _showMessage(error.message);
      return;
    } catch (_) {
      _showMessage('Expertise tidak bisa disimpan.');
      return;
    } finally {
      if (mounted) {
        setState(() => _saving = false);
      }
    }

    if (!mounted) return;
    _showMessage(data['message']?.toString() ?? 'Expertise tersimpan.');
    setState(() {
      _future = _load();
    });
  }

  int _wizardStep(String dlp) => _wizardSteps[dlp] ?? 0;

  void _setWizardStep(String dlp, int step) {
    _wizardSteps[dlp] = step;
  }

  void _showMessage(String message) {
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text(message)));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Expertise'),
        actions: [
          IconButton(
            onPressed: _saving ? null : _reload,
            icon: const Icon(Icons.refresh),
            tooltip: 'Refresh',
          ),
        ],
      ),
      body: FutureBuilder<Map<String, dynamic>>(
        future: _future,
        builder: (context, snapshot) {
          if (snapshot.connectionState != ConnectionState.done) {
            return const LoadingScreen();
          }
          if (snapshot.hasError) {
            return ErrorView(
              message: _message(snapshot.error),
              onRetry: _reload,
            );
          }
          final data = snapshot.data!;
          final item = asMap(data['item']);
          final user = asMap(data['user']);
          _prepareFields(data);
          final isSupervisor = _isSupervisor(user['previlage']?.toString());

          final summaryCard = Card(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(8),
            ),
            child: Padding(
              padding: const EdgeInsets.all(14),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    item['nmpasien']?.toString() ?? '-',
                    style: Theme.of(context).textTheme.titleMedium?.copyWith(
                      fontWeight: FontWeight.w800,
                    ),
                  ),
                  const SizedBox(height: 6),
                  Text(
                    '${item['nofoto'] ?? '-'} / RM ${item['noregister'] ?? '-'}',
                  ),
                  Text(item['reques']?.toString() ?? '-'),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      StatusPill(status: item['status']?.toString() ?? 'NEW'),
                      const SizedBox(width: 8),
                      if (_currentDlp.isNotEmpty)
                        BadgeLabel(
                          text: _currentDlp,
                          color: const Color(0xFF0F766E),
                        ),
                    ],
                  ),
                ],
              ),
            ),
          );

          final expertiseContent = _currentDlp.isEmpty
              ? TemplatePicker(
                  templates: asList(data['templates']),
                  saving: _saving,
                  onUse: _setTemplate,
                )
              : _currentDlp == 'CCI'
              ? CciExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  optionSets: asMap(data['option_sets']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : _currentDlp == 'Kultur'
              ? KulturExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  optionSets: asMap(data['option_sets']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  multiValues: _multiValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : _currentDlp == 'Pewarna Langsung'
              ? PewarnaanLangsungExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  optionSets: asMap(data['option_sets']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  multiValues: _multiValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : _currentDlp == 'Viral Load'
              ? ViralLoadExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  optionSets: asMap(data['option_sets']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : _currentDlp == 'IgM IgG Leptospira'
              ? LeptospiraExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : _currentDlp == 'PCR COVID'
              ? CovidExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : _currentDlp == 'TBC'
              ? TbcExpertiseWizard(
                  item: item,
                  user: user,
                  staffOptions: asMap(data['staff_options']),
                  textControllers: _textControllers,
                  selectValues: _selectValues,
                  multiValues: _multiValues,
                  staffValues: _staffValues,
                  criticalValue: _criticalValue,
                  isSupervisor: isSupervisor,
                  saving: _saving,
                  onCriticalChanged: (value) =>
                      setState(() => _criticalValue = value),
                  onChanged: () => setState(() {}),
                  onSave: _save,
                  initialStep: _wizardStep(_currentDlp),
                  onStepChanged: (step) => _setWizardStep(_currentDlp, step),
                )
              : SingleChildScrollView(
                  padding: const EdgeInsets.only(bottom: 16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      PatientStaffPanel(
                        item: item,
                        user: user,
                        staffOptions: asMap(data['staff_options']),
                        staffValues: _staffValues,
                        onChanged: () => setState(() {}),
                      ),
                      const SizedBox(height: 12),
                      ExpertiseForm(
                        dlp: _currentDlp,
                        fields: asList(data['fields']),
                        textControllers: _textControllers,
                        selectValues: _selectValues,
                        multiValues: _multiValues,
                        onChanged: () => setState(() {}),
                      ),
                      const SizedBox(height: 12),
                      ExpertiseActions(
                        isSupervisor: isSupervisor,
                        saving: _saving,
                        onSave: _save,
                      ),
                    ],
                  ),
                );

          if (_currentDlp.isEmpty) {
            return ListView(
              padding: const EdgeInsets.all(16),
              children: [
                summaryCard,
                const SizedBox(height: 14),
                expertiseContent,
              ],
            );
          }

          return Padding(
            padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
            child: Column(
              children: [
                summaryCard,
                const SizedBox(height: 14),
                Expanded(child: expertiseContent),
              ],
            ),
          );
        },
      ),
    );
  }
}
