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

class TbcExpertiseWizard extends StatefulWidget {
  const TbcExpertiseWizard({
    super.key,
    required this.item,
    required this.user,
    required this.staffOptions,
    required this.textControllers,
    required this.selectValues,
    required this.multiValues,
    required this.staffValues,
    required this.criticalValue,
    required this.isSupervisor,
    required this.saving,
    required this.onCriticalChanged,
    required this.onChanged,
    required this.onSave,
    required this.initialStep,
    required this.onStepChanged,
  });

  final Map<String, dynamic> item;
  final Map<String, dynamic> user;
  final Map<String, dynamic> staffOptions;
  final Map<String, TextEditingController> textControllers;
  final Map<String, String> selectValues;
  final Map<String, Set<String>> multiValues;
  final Map<String, String> staffValues;
  final bool criticalValue;
  final bool isSupervisor;
  final bool saving;
  final ValueChanged<bool> onCriticalChanged;
  final VoidCallback onChanged;
  final ValueChanged<String> onSave;
  final int initialStep;
  final ValueChanged<int> onStepChanged;

  @override
  State<TbcExpertiseWizard> createState() => _TbcExpertiseWizardState();
}

class _TbcExpertiseWizardState extends State<TbcExpertiseWizard> {
  late int _step;

  @override
  void initState() {
    super.initState();
    _step = widget.initialStep.clamp(0, 6);
  }

  @override
  void didUpdateWidget(covariant TbcExpertiseWizard oldWidget) {
    super.didUpdateWidget(oldWidget);
    final nextStep = widget.initialStep.clamp(0, 6);
    if (nextStep != _step) {
      _step = nextStep;
    }
  }

  void _setStep(int step) {
    final nextStep = step.clamp(0, 6);
    setState(() => _step = nextStep);
    widget.onStepChanged(nextStep);
  }

  @override
  Widget build(BuildContext context) {
    return ExpertiseWizardShell(
      currentStep: _step,
      onStepChanged: _setStep,
      steps: [
        Step(
          title: const Text('Pasien & Petugas'),
          isActive: _step == 0,
          content: PatientStaffPanel(
            item: widget.item,
            user: widget.user,
            staffOptions: widget.staffOptions,
            staffValues: widget.staffValues,
            onChanged: widget.onChanged,
          ),
        ),
        Step(
          title: const Text('Riwayat & Identitas Nasional'),
          isActive: _step == 1,
          content: _historyAndIdentity(),
        ),
        Step(
          title: const Text('Jenis Pemeriksaan'),
          isActive: _step == 2,
          content: _testType(),
        ),
        Step(
          title: const Text('Hasil Pemeriksaan'),
          isActive: _step == 3,
          content: _examinationResultByType(),
        ),
        Step(
          title: const Text('Tes Kepekaan Antibiotik'),
          isActive: _step == 4,
          content: _antibioticSensitivity(),
        ),
        Step(
          title: const Text('Data Alat'),
          isActive: _step == 5,
          content: _toolData(),
        ),
        Step(
          title: const Text('Expertise'),
          isActive: _step == 6,
          content: _finalExpertise(),
        ),
      ],
    );
  }

  Widget _historyAndIdentity() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionTitle('Jenis Terduga / Pasien TBC'),
        _multiSelect('jenis_pasien_tbc', 'Jenis Terduga / Pasien TBC', const [
          'TBC SO',
          'TBC RO',
          'Anak',
          'HIV',
          'DM',
        ]),
        _text('id_noidsediaan', 'No. Identitas Sediaan'),
        _text(
          'id_tanggalpengambilancontohuji',
          'Tanggal Pengambilan Contoh Uji',
        ),
        _text('id_tanggalpengirimancontohuji', 'Tanggal Pengiriman Contoh Uji'),
        _select(
          'id_lamariwayatpengobatantb',
          'Lama Riwayat Pengobatan Terduga/Pasien TBC',
          const [
            'Riwayat Pengobatan >= 5 tahun',
            'Riwayat Pengobatan < 5 tahun',
          ],
        ),
        _select('id_lokasianatomi', 'Lokasi Anatomi', const [
          'Paru',
          'Ekstraparu',
        ]),
        _text('id_ekstraparu', 'Ekstraparu'),
        _select('id_alasanpemeriksaan', 'Alasan Pemeriksaan', const [
          'Diagnosis TBC',
          'Diagnosis Baseline TBC',
          'Akhir Pengobatan',
        ]),
        _text(
          'id_bulankemajuantbfollow',
          'Pemantauan kemajuan pengobatan (Bulan ke)',
        ),
        _text('id_bulanpemeriksaanulang', 'Pemeriksaan ulang (Bulan ke)'),
        _text(
          'id_bulanpemeriksaansetelahselesai',
          'Pemeriksaan setelah selesai pengobatan (Bulan ke)',
        ),
        _text('id_noregfasyankes', 'No.Reg.TBC/TBC RO Fasyankes'),
        _text('id_noregkota', 'No.Reg.TBC/TBC RO Kab/Kota'),
        _select('id_contohuji', 'Contoh Uji', const ['Dahak', 'Lainnya']),
        _text('id_contohujilainnya', 'Contoh Uji Lainnya'),
        _multiSelect('visual_dahak_sewaktu', 'Visual dahak Sewaktu', const [
          'Nanah Lendir',
          'Bercak darah',
          'Air liur',
        ]),
        _multiSelect('visual_dahak_pagi', 'Visual dahak Pagi', const [
          'Nanah Lendir',
          'Bercak darah',
          'Air liur',
        ]),
      ],
    );
  }

  Widget _testType() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionTitle('Jenis Pemeriksaan'),
        _select('id_jenispemeriksaantb', 'Jenis Pemeriksaan', _tbcTestTypes),
      ],
    );
  }

  Widget _examinationResultByType() {
    final type = widget.selectValues['id_jenispemeriksaantb'] ?? '';
    if (type == 'TCM XDR (Xpert)') {
      return _xdrResult();
    }
    if (type == 'Biakan') {
      return _cultureResult();
    }
    if (_tcmRifTypes.contains(type)) {
      return _tcmMtbRifResult();
    }
    return _microscopicResult();
  }

  Widget _microscopicResult() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionTitle('Hasil Pemeriksaan Mikroskopis'),
        _text('hasilpemeriksaantmikroskopis_tglsewaktu', 'Tanggal Sewaktu'),
        _select(
          'hasilpemeriksaantmikroskopis_hasilsewaktu',
          'Hasil Sewaktu',
          _tbMicroscopeResults,
        ),
        _text('hasilpemeriksaantmikroskopis_tglpagi', 'Tanggal Pagi'),
        _select(
          'hasilpemeriksaantmikroskopis_hasilpagi',
          'Hasil Pagi',
          _tbMicroscopeResults,
        ),
      ],
    );
  }

  Widget _tcmMtbRifResult() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionTitle('Hasil Pemeriksaan TCM MTB Rif'),
        _text('hasilpemeriksaanttcmmtbrifxpert_tglsewaktu', 'Tanggal Sewaktu'),
        _text('hasilpemeriksaanttcmmtbrifxpert_kodeunik', 'Kode Unik Sewaktu'),
        _select(
          'hasilpemeriksaanttcmmtbrifxpert_hasilsewaktu',
          'Hasil Sewaktu',
          _tcmMtbRifResults,
        ),
        _text('hasilpemeriksaanttcmmtbrifxpert_tglpagi', 'Tanggal Pagi'),
        _text('hasilpemeriksaanttcmmtbrifxpert_kodeunikpagi', 'Kode Unik Pagi'),
        _select(
          'hasilpemeriksaanttcmmtbrifxpert_hasilpagi',
          'Hasil Pagi',
          _tcmMtbRifResults,
        ),
      ],
    );
  }

  Widget _cultureResult() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionTitle('Hasil Biakan'),
        _text('hasilpemeriksaantbbiakan_tgl', 'Tanggal Mikroskopis'),
        _select(
          'hasilpemeriksaantbbiakan_pagi',
          'Mikroskopis Pagi',
          _tbMicroscopeResults,
        ),
        _select(
          'hasilpemeriksaantbbiakan_sewaktu',
          'Mikroskopis Sewaktu',
          _tbMicroscopeResults,
        ),
        _text('hasilpemeriksaantbbiakan_tglbiakan', 'Tanggal Biakan'),
        _select(
          'hasilpemeriksaantbbiakan_hasilbiakanmgit',
          'Hasil Biakan (MGIT)',
          const ['Pos', 'Neg', 'NTM', 'KTM', 'TDL'],
        ),
        _select(
          'hasilpemeriksaantbbiakan_hasilbiakanlj',
          'Hasil Biakan (LJ)',
          const ['3+', '2+', '1+', '1-9', 'Neg', 'NTM', 'KTM', 'TDL'],
        ),
      ],
    );
  }

  Widget _xdrResult() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _sectionTitle('TCM XDR (Xpert) - Pagi'),
        _text('hasilpemeriksaanttcmmtbxdrxpert_tglpagi', 'Tanggal Pagi'),
        _text('hasilpemeriksaanttcmmtbxdrxpert_kodeunikpagi', 'Kode Unik Pagi'),
        _xdrPanel('pagi'),
        const SizedBox(height: 12),
        _sectionTitle('TCM XDR (Xpert) - Sewaktu'),
        _text('hasilpemeriksaanttcmmtbxdrxpert_tglsewaktu', 'Tanggal Sewaktu'),
        _text('hasilpemeriksaanttcmmtbxdrxpert_kodeunik', 'Kode Unik Sewaktu'),
        _xdrPanel('sewaktu'),
      ],
    );
  }

  Widget _xdrPanel(String prefix) {
    final normalized = prefix == 'pagi' ? 'pagi' : 'sewaktu';
    final inhLowField = prefix == 'pagi'
        ? 'hasilpemeriksaanttcmmtbxdrxpert_paginhlow'
        : 'hasilpemeriksaanttcmmtbxdrxpert_sewaktunhlow';
    return Card(
      margin: const EdgeInsets.only(bottom: 8),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          children: [
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_$normalized',
              'TCM XDR',
              _xdrValidityResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}mtb',
              'MTB',
              const ['Detected', 'Not Detected'],
            ),
            _select(inhLowField, 'H Low', _xdrSirResults),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}h',
              'H',
              _xdrSirResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}fqlow',
              'FQ Low',
              _xdrSirResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}fq',
              'FQ',
              _xdrSirResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}amk',
              'Amk',
              _xdrSirResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}km',
              'Km',
              _xdrSirResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}cm',
              'Cm',
              _xdrSirResults,
            ),
            _select(
              'hasilpemeriksaanttcmmtbxdrxpert_${normalized}eto',
              'Eto',
              _xdrSirResults,
            ),
          ],
        ),
      ),
    );
  }

  Widget _antibioticSensitivity() {
    return AntibioticSensitivityPanel(
      textControllers: widget.textControllers,
      selectValues: widget.selectValues,
      onChanged: widget.onChanged,
    );
  }

  Widget _toolData() {
    return ToolDataPanel(
      textControllers: widget.textControllers,
      selectValues: widget.selectValues,
      onChanged: widget.onChanged,
    );
  }

  Widget _finalExpertise() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        ExpertiseHtmlEditor(
          controller: widget.textControllers['keterangan'] ??=
              TextEditingController(),
          label: 'Expertise',
        ),
        CheckboxListTile(
          value: widget.criticalValue,
          onChanged: (value) => widget.onCriticalChanged(value ?? false),
          contentPadding: EdgeInsets.zero,
          controlAffinity: ListTileControlAffinity.leading,
          title: const Text('Nilai Kritis'),
        ),
        FilledButton.icon(
          onPressed: widget.saving ? null : () => widget.onSave('Draft'),
          icon: widget.saving
              ? const SizedBox.square(
                  dimension: 18,
                  child: CircularProgressIndicator(strokeWidth: 2),
                )
              : const Icon(Icons.save_outlined),
          label: const Text('Save as Draft'),
        ),
        if (widget.isSupervisor) ...[
          OutlinedButton.icon(
            onPressed: widget.saving
                ? null
                : () => widget.onSave('preliminary'),
            icon: const Icon(Icons.done_all_outlined),
            label: const Text('Save Preliminary result'),
          ),
          OutlinedButton.icon(
            onPressed: widget.saving ? null : () => widget.onSave('verifikasi'),
            icon: const Icon(Icons.verified_outlined),
            label: const Text('Save Final Result'),
          ),
        ] else ...[
          OutlinedButton.icon(
            onPressed: widget.saving
                ? null
                : () => widget.onSave('Permohonan Verifikasi'),
            icon: const Icon(Icons.send_outlined),
            label: const Text('Save and Send To SPV'),
          ),
          OutlinedButton.icon(
            onPressed: widget.saving
                ? null
                : () => widget.onSave('Permohonan Verifikasi Preliminary'),
            icon: const Icon(Icons.outgoing_mail),
            label: const Text('Kirim SPV Preliminary'),
          ),
        ],
      ],
    );
  }

  Widget _sectionTitle(String title, {bool compact = false}) {
    return Padding(
      padding: EdgeInsets.only(bottom: compact ? 8 : 12),
      child: Text(
        title,
        style: Theme.of(context).textTheme.titleSmall?.copyWith(
          fontWeight: FontWeight.w800,
          color: const Color(0xFF0F766E),
        ),
      ),
    );
  }

  // ignore: unused_element
  Widget _toolSection({
    required String title,
    required String bacteriaField,
    String? antibioticField,
    required String sirField,
    required String colonyField,
    required String colonyTextField,
    required String printField,
  }) {
    return Card(
      margin: const EdgeInsets.only(bottom: 12),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _sectionTitle(title, compact: true),
            _text(bacteriaField, 'Bakteri'),
            if (antibioticField != null)
              _text(antibioticField, 'Set Antibiotik'),
            _select(sirField, 'SIR', _sirOptions),
            _select(colonyField, 'Hitung Koloni', _colonyOptions),
            _text(colonyTextField, 'Hitung Koloni Lainnya'),
            _select(printField, 'Cetak', const ['YA', 'TIDAK']),
          ],
        ),
      ),
    );
  }

  Widget _select(String name, String label, List<String> options) {
    final current = widget.selectValues[name];
    final effectiveOptions = [
      if (current != null && current.isNotEmpty && !options.contains(current))
        current,
      ...options,
    ];
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: DropdownButtonFormField<String>(
        initialValue:
            current != null &&
                current.isNotEmpty &&
                effectiveOptions.contains(current)
            ? current
            : null,
        isExpanded: true,
        decoration: InputDecoration(
          labelText: label,
          border: const OutlineInputBorder(),
        ),
        items: effectiveOptions
            .map(
              (option) => DropdownMenuItem(value: option, child: Text(option)),
            )
            .toList(),
        onChanged: (value) {
          widget.selectValues[name] = value ?? '';
          widget.onChanged();
        },
      ),
    );
  }

  Widget _multiSelect(String name, String label, List<String> options) {
    final selected = widget.multiValues[name] ?? <String>{};
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: CompactMultiSelectField(
        label: label,
        options: options,
        selected: selected,
        onChanged: (value) {
          widget.multiValues[name] = value;
          widget.onChanged();
        },
      ),
    );
  }

  Widget _text(
    String name,
    String label, {
    int minLines = 1,
    int maxLines = 1,
  }) {
    final controller = widget.textControllers[name] ??= TextEditingController();
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: TextField(
        controller: controller,
        minLines: minLines,
        maxLines: maxLines,
        decoration: InputDecoration(
          labelText: label,
          border: const OutlineInputBorder(),
        ),
      ),
    );
  }
}

const List<String> _tbcTestTypes = [
  'Mikroskopis',
  'TCM MTB Rif (Xpert)',
  'TCM XDR (Xpert)',
  'TCM MTB Rif (Truenat)',
  'TCM MTB Rif INH (BDMAX)',
  'PCR Open System',
  'LPA lini 1',
  'LPA lini 2',
  'Biakan',
  'Paket standar uji kepekaan',
];

const Set<String> _tcmRifTypes = {
  'TCM MTB Rif (Xpert)',
  'TCM MTB Rif (Truenat)',
  'TCM MTB Rif INH (BDMAX)',
  'LPA lini 1',
  'LPA lini 2',
};

const List<String> _tbMicroscopeResults = ['+++', '++', '+', '1-9', 'Neg'];

const List<String> _tcmMtbRifResults = [
  'Neg',
  'Rif Sen',
  'Rif Res',
  'Rif Indet',
  'Invalid',
  'Error',
  'No result',
];

const List<String> _xdrValidityResults = [
  'Valid',
  'Invalid',
  'No Result',
  'Error',
];

const List<String> _xdrSirResults = [
  'S',
  'I',
  'R',
  'Invalid',
  'Error',
  'No Result',
];
