import 'dart:async';
import 'dart:math';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;

import '../../../core/api/pocketbase_client.dart';
import '../../../core/providers/auth_provider.dart';
import '../../../core/services/pricing_service.dart';
import '../../../core/theme/app_theme.dart';
import '../../../models/job.dart';
import '../../../models/patient.dart';
import '../../../models/prosthetic_product.dart';
import '../../../models/tenant.dart';
import '../../lab/discounts/discount_repository.dart';
import '../../lab/products/lab_products_repository.dart';
import 'clinic_jobs_repository.dart';
import '../patients/clinic_patients_repository.dart';

enum _PatientEntryMode {
  selectExisting,
  createNew,
}

String _mimeFromExt(String ext) => switch (ext) {
      'jpg' || 'jpeg' => 'image/jpeg',
      'png' => 'image/png',
      'webp' => 'image/webp',
      'pdf' => 'application/pdf',
      'stl' => 'model/stl',
      'obj' => 'model/obj',
      'ply' => 'model/ply',
      'zip' => 'application/zip',
      'mp3' => 'audio/mpeg',
      'mp4' => 'video/mp4',
      'opus' => 'audio/opus',
      _ => 'application/octet-stream',
    };

class NewJobScreen extends ConsumerStatefulWidget {
  const NewJobScreen({super.key});

  @override
  ConsumerState<NewJobScreen> createState() => _NewJobScreenState();
}

class _NewJobScreenState extends ConsumerState<NewJobScreen> {
  final _formKey = GlobalKey<FormState>();

  // Form fields
  Map<String, dynamic>? _selectedLab;
  Patient? _selectedPatient;
  final _patientNameController = TextEditingController();
  final _patientLastNameController = TextEditingController();
  final _patientCodeController = TextEditingController();
  ProstheticType? _selectedProstheticType;
  JobWorkflowType? _selectedWorkflowType = JobWorkflowType.geleneksel;
  final Set<int> _selectedTeeth = {};
  final _colorController = TextEditingController();
  final _descriptionController = TextEditingController();
  DateTime? _dueDate;
  bool _provaRequired = true;
  _PatientEntryMode _patientEntryMode = _PatientEntryMode.selectExisting;

  // State
  List<Map<String, dynamic>> _labs = [];
  bool _labsLoading = true;
  bool _isSubmitting = false;
  String? _labsError;

  // File upload
  final List<PlatformFile> _pendingFiles = [];

  // Patient search
  final _patientSearchController = TextEditingController();
  List<Patient> _patientResults = [];
  bool _patientSearchLoading = false;
  Timer? _patientSearchDebounce;

  // Price preview
  List<ProstheticProduct> _availableProducts = [];
  ProstheticProduct? _selectedProduct;
  ProstheticProduct? _labProduct;
  PricingBreakdown? _pricingBreakdown;
  double? _effectivePrice;
  bool _priceLoading = false;
  String? _productAvailabilityMessage;

  @override
  void initState() {
    super.initState();
    _loadLabs();
  }

  @override
  void dispose() {
    _patientSearchDebounce?.cancel();
    _patientNameController.dispose();
    _patientLastNameController.dispose();
    _patientCodeController.dispose();
    _colorController.dispose();
    _descriptionController.dispose();
    _patientSearchController.dispose();
    super.dispose();
  }

  Future<void> _loadLabs() async {
    setState(() {
      _labsLoading = true;
      _labsError = null;
    });
    try {
      final tenantId = ref.read(authProvider).activeTenant!.tenant.id;
      final labs =
          await ClinicJobsRepository.instance.listApprovedLabs(tenantId);
      setState(() {
        _labs = labs;
        _labsLoading = false;
      });
    } catch (e) {
      setState(() {
        _labsError = e.toString();
        _labsLoading = false;
      });
    }
  }

  Future<void> _refreshProductsAndPrice() async {
    if (_selectedLab == null || _selectedProstheticType == null) {
      setState(() {
        _availableProducts = [];
        _selectedProduct = null;
        _labProduct = null;
        _pricingBreakdown = null;
        _effectivePrice = null;
        _productAvailabilityMessage = null;
      });
      return;
    }
    final labId = _selectedLab!['id'] as String;
    final ptValue = _selectedProstheticType!.value;
    final clinicTenantId = ref.read(authProvider).activeTenant!.tenant.id;

    setState(() => _priceLoading = true);
    try {
      final products = await LabProductsRepository.instance.listProducts(
        labId,
        isActive: true,
      );
      final matchingProducts = products
          .where(
            (p) =>
                p.prostheticType == ptValue ||
                parseProstheticTypeValue(p.prostheticType) ==
                    _selectedProstheticType,
          )
          .toList();

      ProstheticProduct? product;
      if (_selectedProduct != null) {
        try {
          product = matchingProducts.firstWhere(
            (p) => p.id == _selectedProduct!.id,
          );
        } catch (_) {
          product = null;
        }
      }
      product ??= matchingProducts.isNotEmpty ? matchingProducts.first : null;

      if (product == null) {
        setState(() {
          _availableProducts = matchingProducts;
          _selectedProduct = null;
          _labProduct = null;
          _pricingBreakdown = null;
          _effectivePrice = null;
          _productAvailabilityMessage =
              'Bu laboratuvarda seçtiğiniz protez türü için ürün tanımlı değil.';
          _priceLoading = false;
        });
        return;
      }

      if (product.unitPrice == null) {
        setState(() {
          _availableProducts = matchingProducts;
          _selectedProduct = product;
          _labProduct = product;
          _pricingBreakdown = null;
          _effectivePrice = null;
          _productAvailabilityMessage =
              'Seçilen ürün laboratuvarda mevcut ancak fiyatı tanımlı değil. Laboratuvarın fiyat tanımlaması gerekiyor.';
          _priceLoading = false;
        });
        return;
      }
      final discounts = await DiscountRepository.instance.listDiscounts(labId);
      final breakdown = PricingService.instance.calculate(
        product: product,
        prostheticType: _selectedProstheticType!,
        memberCount: _selectedTeeth.length,
        clinicTenantId: clinicTenantId,
        discounts: discounts,
        teeth: _selectedTeeth,
      );
      setState(() {
        _availableProducts = matchingProducts;
        _selectedProduct = product;
        _labProduct = product;
        _pricingBreakdown = breakdown;
        _effectivePrice = breakdown.finalAmount;
        _productAvailabilityMessage = null;
        _priceLoading = false;
      });
    } catch (_) {
      setState(() {
        _availableProducts = [];
        _selectedProduct = null;
        _labProduct = null;
        _pricingBreakdown = null;
        _effectivePrice = null;
        _productAvailabilityMessage =
            'Ürün ve fiyat bilgisi alınırken bir hata oluştu.';
        _priceLoading = false;
      });
    }
  }

  bool get _hasMissingProductForType =>
      _selectedLab != null &&
      _selectedProstheticType != null &&
      !_priceLoading &&
      _availableProducts.isEmpty;

  bool get _hasSelectedProductWithoutPrice =>
      _selectedProduct != null && _selectedProduct!.unitPrice == null;

  bool get _canSubmitJob =>
      !_isSubmitting &&
      !_priceLoading &&
      !_hasMissingProductForType &&
      !_hasSelectedProductWithoutPrice;

  Future<void> _searchPatients(String query) async {
    final normalizedQuery = query.trim();
    if (normalizedQuery.length < 2) {
      if (!mounted) return;
      setState(() {
        _patientResults = [];
        _patientSearchLoading = false;
      });
      return;
    }
    setState(() => _patientSearchLoading = true);
    try {
      final tenantId = ref.read(authProvider).activeTenant!.tenant.id;
      final results = await ClinicPatientsRepository.instance
          .listPatients(tenantId, search: normalizedQuery, limit: 10);
      if (!mounted || _patientSearchController.text.trim() != normalizedQuery) {
        return;
      }
      setState(() {
        _patientResults = results;
        _patientSearchLoading = false;
      });
    } catch (_) {
      if (!mounted) return;
      setState(() => _patientSearchLoading = false);
    }
  }

  void _onPatientSearchChanged(String value) {
    _selectedPatient = null;
    _patientSearchDebounce?.cancel();
    final query = value.trim();
    if (query.length < 2) {
      setState(() {
        _patientResults = [];
        _patientSearchLoading = false;
      });
      return;
    }
    setState(() => _patientSearchLoading = true);
    _patientSearchDebounce = Timer(
      const Duration(milliseconds: 300),
      () => _searchPatients(query),
    );
  }

  void _setPatientEntryMode(_PatientEntryMode mode) {
    _patientSearchDebounce?.cancel();
    setState(() {
      _patientEntryMode = mode;
      _selectedPatient = null;
      _patientResults = [];
      _patientSearchLoading = false;
      _patientSearchController.clear();
      _patientNameController.clear();
      _patientLastNameController.clear();
      _patientCodeController.clear();
    });
  }

  Future<void> _pickDueDate() async {
    final pickedDate = await showDatePicker(
      context: context,
      initialDate: DateTime.now().add(const Duration(days: 7)),
      firstDate: DateTime.now(),
      lastDate: DateTime.now().add(const Duration(days: 365)),
    );
    if (pickedDate == null || !mounted) return;
    final pickedTime = await showTimePicker(
      context: context,
      initialTime: const TimeOfDay(hour: 17, minute: 0),
    );
    if (!mounted) return;
    setState(() {
      _dueDate = DateTime(
        pickedDate.year,
        pickedDate.month,
        pickedDate.day,
        pickedTime?.hour ?? 17,
        pickedTime?.minute ?? 0,
      );
    });
  }

  String _generateProtocolNo() {
    final now = DateTime.now();
    final date =
        '${now.year}${now.month.toString().padLeft(2, '0')}${now.day.toString().padLeft(2, '0')}';
    const chars = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ';
    final rand =
        List.generate(4, (_) => chars[Random().nextInt(chars.length)]).join();
    return 'PR-$date-$rand';
  }

  Future<void> _submit() async {
    if (!_formKey.currentState!.validate()) return;
    if (_selectedLab == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Lütfen bir laboratuvar seçin.')),
      );
      return;
    }
    if (_selectedProstheticType == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Lütfen protez türünü seçin.')),
      );
      return;
    }
    if (_hasMissingProductForType) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text(
            'Bu laboratuvarda seçtiğiniz protez türü için ürün tanımlı değil.',
          ),
        ),
      );
      return;
    }
    if (_hasSelectedProductWithoutPrice) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text(
            'Seçilen ürünün fiyatı laboratuvarda tanımlı değil. İş açmadan önce fiyat tanımlanmalı.',
          ),
        ),
      );
      return;
    }
    if (_selectedTeeth.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('En az bir diş seçmelisiniz.')),
      );
      return;
    }

    setState(() => _isSubmitting = true);
    try {
      final auth = ref.read(authProvider);
      final tenantId = auth.activeTenant!.tenant.id;
      final clinicName = auth.activeTenant!.tenant.companyName;
      final rawCode = _patientCodeController.text.trim();
      final rawFirstName = _patientNameController.text.trim();
      final rawLastName = _patientLastNameController.text.trim();
      Patient? patient = _selectedPatient;
      if (_patientEntryMode == _PatientEntryMode.selectExisting &&
          patient == null &&
          _patientSearchController.text.trim().isNotEmpty) {
        throw 'Lütfen listeden bir hasta seçin veya "Yeni Hasta Oluştur" moduna geçin.';
      }
      final protocolNo = patient?.patientCode ??
          (rawCode.isNotEmpty ? rawCode : _generateProtocolNo());
      if (_patientEntryMode == _PatientEntryMode.createNew &&
          patient == null &&
          (rawFirstName.isNotEmpty || rawLastName.isNotEmpty)) {
        patient = await ClinicPatientsRepository.instance.createPatient(
          tenantId: tenantId,
          patientCode: protocolNo,
          firstName: rawFirstName.isNotEmpty ? rawFirstName : null,
          lastName: rawLastName.isNotEmpty ? rawLastName : null,
        );
      }
      final selectedLabTenant = Tenant.fromJson(_selectedLab!);
      final workflowSteps = buildJobWorkflowPreset(
        prostheticType: _selectedProstheticType!,
        workflowType: _selectedWorkflowType,
        provaRequired: _provaRequired,
        optionalSteps: selectedLabTenant.workflowOverrideSteps,
      ).steps;
      final job = await ClinicJobsRepository.instance.createJob(
        clinicTenantId: tenantId,
        labTenantId: _selectedLab!['id'] as String,
        clinicName: clinicName,
        labName: _selectedLab!['company_name'] as String? ?? 'Laboratuvar',
        patientCode: protocolNo,
        prostheticId: _selectedProduct?.id,
        prostheticType: _selectedProstheticType!,
        teeth: _selectedTeeth.map((t) => t.toString()).toList()..sort(),
        patientId: patient?.id,
        color: _colorController.text.trim().isNotEmpty
            ? _colorController.text.trim()
            : null,
        description: _descriptionController.text.trim().isNotEmpty
            ? _descriptionController.text.trim()
            : null,
        dueDate: _dueDate?.toIso8601String(),
        price: _effectivePrice,
        currency: _labProduct?.currency,
        workflowType: _selectedWorkflowType,
        provaRequired: _provaRequired,
        workflowSteps: workflowSteps.map((step) => step.value).toList(),
      );

      // Upload pending files
      if (_pendingFiles.isNotEmpty) {
        final pb = PocketBaseClient.instance.pb;
        final token = pb.authStore.token;
        final uploaderId =
            (pb.authStore.record?.id) ?? (auth.profile?.id ?? '');
        for (final file in _pendingFiles) {
          final bytes = file.bytes;
          if (bytes == null) continue;
          final ext = (file.extension ?? '').toLowerCase();
          final kind = (ext == 'stl' || ext == 'obj' || ext == 'ply')
              ? 'scan'
              : (ext == 'pdf')
                  ? 'document'
                  : 'image';
          final mimeType = _mimeFromExt(ext);
          final req = http.MultipartRequest(
            'POST',
            Uri.parse(
                'https://pocket.kovaksoft.com/api/collections/job_files/records'),
          )
            ..headers['Authorization'] = 'Bearer $token'
            ..fields['job_id'] = job.id
            ..fields['clinic_tenant_id'] = job.clinicTenantId
            ..fields['lab_tenant_id'] = job.labTenantId
            ..fields['uploaded_by'] = uploaderId
            ..fields['kind'] = kind
            ..fields['name'] = file.name
            ..fields['size'] = bytes.length.toString()
            ..fields['mime_type'] = mimeType
            ..files.add(http.MultipartFile.fromBytes(
              'file',
              bytes,
              filename: file.name,
            ));
          final response = await req.send();
          if (response.statusCode < 200 || response.statusCode >= 300) {
            final body = await response.stream.bytesToString();
            debugPrint('File upload failed: ${response.statusCode} $body');
          }
        }
      }

      if (mounted) {
        context.go('/clinic/jobs/${job.id}');
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Hata: $e')),
        );
      }
    } finally {
      if (mounted) setState(() => _isSubmitting = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Yeni İş')),
      body: Form(
        key: _formKey,
        child: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            // Lab selection
            const _SectionLabel(label: 'Laboratuvar *'),
            if (_labsLoading)
              const Center(child: CircularProgressIndicator())
            else if (_labsError != null)
              Row(
                children: [
                  Text('Hata: $_labsError',
                      style: const TextStyle(color: AppColors.cancelled)),
                  TextButton(
                    onPressed: _loadLabs,
                    child: const Text('Tekrar Dene'),
                  ),
                ],
              )
            else
              DropdownButtonFormField<Map<String, dynamic>>(
                initialValue: _selectedLab,
                decoration: const InputDecoration(
                  hintText: 'Laboratuvar seçin',
                ),
                items: _labs
                    .map(
                      (lab) => DropdownMenuItem(
                        value: lab,
                        child: Text(lab['company_name'] as String? ?? ''),
                      ),
                    )
                    .toList(),
                onChanged: (val) {
                  setState(() {
                    _selectedLab = val;
                    _selectedProduct = null;
                  });
                  _refreshProductsAndPrice();
                },
                validator: (val) =>
                    val == null ? 'Laboratuvar seçimi zorunludur' : null,
              ),
            const SizedBox(height: 16),

            const _SectionLabel(label: 'Hasta / Protokol'),
            const SizedBox(height: 8),
            SegmentedButton<_PatientEntryMode>(
              segments: const [
                ButtonSegment(
                  value: _PatientEntryMode.selectExisting,
                  icon: Icon(Icons.search_rounded),
                  label: Text('Mevcut Hasta'),
                ),
                ButtonSegment(
                  value: _PatientEntryMode.createNew,
                  icon: Icon(Icons.person_add_alt_1_rounded),
                  label: Text('Yeni Hasta'),
                ),
              ],
              selected: {_patientEntryMode},
              onSelectionChanged: (selection) {
                _setPatientEntryMode(selection.first);
              },
            ),
            if (_patientEntryMode == _PatientEntryMode.selectExisting) ...[
              const SizedBox(height: 8),
              TextField(
                controller: _patientSearchController,
                decoration: const InputDecoration(
                  hintText: 'Ad, soyad veya kod ile arayın...',
                  prefixIcon: Icon(Icons.search),
                  helperText: 'Yazmaya başlayınca otomatik arar',
                ),
                onChanged: _onPatientSearchChanged,
              ),
              if (_patientSearchLoading)
                const Padding(
                  padding: EdgeInsets.all(8),
                  child: Center(child: CircularProgressIndicator()),
                ),
              if (!_patientSearchLoading &&
                  _patientSearchController.text.trim().length >= 2 &&
                  _patientResults.isEmpty)
                const ListTile(
                  dense: true,
                  leading: Icon(Icons.info_outline),
                  title: Text('Hasta bulunamadı'),
                  subtitle: Text(
                      'İsterseniz "Yeni Hasta" modundan manuel ekleyebilirsiniz.'),
                ),
              ..._patientResults.map(
                (p) => ListTile(
                  dense: true,
                  leading: const Icon(Icons.person_outline),
                  title: Text(p.displayName),
                  subtitle: Text(p.patientCode),
                  onTap: () {
                    setState(() {
                      _selectedPatient = p;
                      _patientNameController.text = p.firstName ?? '';
                      _patientLastNameController.text = p.lastName ?? '';
                      _patientCodeController.text = p.patientCode;
                      _patientResults.clear();
                    });
                  },
                ),
              ),
              if (_selectedPatient != null)
                Container(
                  margin: const EdgeInsets.only(top: 8),
                  padding: const EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: AppColors.successBg,
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(
                      color: AppColors.success.withValues(alpha: 0.25),
                    ),
                  ),
                  child: Row(
                    children: [
                      const Icon(Icons.person, color: AppColors.success),
                      const SizedBox(width: 8),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              _selectedPatient!.displayName,
                              style: const TextStyle(
                                fontWeight: FontWeight.w700,
                                color: AppColors.success,
                              ),
                            ),
                            Text(
                              _selectedPatient!.patientCode,
                              style: TextStyle(
                                fontSize: 12,
                                color: AppColors.success.withValues(alpha: 0.8),
                              ),
                            ),
                          ],
                        ),
                      ),
                      TextButton(
                        onPressed: () {
                          setState(() {
                            _selectedPatient = null;
                            _patientNameController.clear();
                            _patientLastNameController.clear();
                            _patientCodeController.clear();
                          });
                        },
                        child: const Text('Temizle'),
                      ),
                    ],
                  ),
                ),
            ] else ...[
              Row(
                children: [
                  Expanded(
                    child: TextFormField(
                      controller: _patientNameController,
                      decoration: const InputDecoration(
                        hintText: 'Hasta adı',
                      ),
                    ),
                  ),
                  const SizedBox(width: 8),
                  Expanded(
                    child: TextFormField(
                      controller: _patientLastNameController,
                      decoration: const InputDecoration(
                        hintText: 'Hasta soyadı',
                      ),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 8),
              TextFormField(
                controller: _patientCodeController,
                decoration: const InputDecoration(
                  hintText: 'Protokol no (boş bırakılırsa otomatik üretilir)',
                ),
              ),
            ],
            const SizedBox(height: 16),

            // Prosthetic type
            const _SectionLabel(label: 'Protez Türü *'),
            DropdownButtonFormField<ProstheticType>(
              initialValue: _selectedProstheticType,
              decoration: const InputDecoration(
                hintText: 'Protez türü seçin',
              ),
              items: visibleProstheticTypes
                  .map(
                    (pt) => DropdownMenuItem(
                      value: pt,
                      child: Text(pt.label),
                    ),
                  )
                  .toList(),
              onChanged: (val) {
                setState(() {
                  _selectedProstheticType = val;
                  _selectedProduct = null;
                });
                _refreshProductsAndPrice();
              },
              validator: (val) => val == null ? 'Protez türü zorunludur' : null,
            ),
            const SizedBox(height: 16),

            const _SectionLabel(label: 'Ürün'),
            DropdownButtonFormField<ProstheticProduct>(
              initialValue: _selectedProduct,
              decoration: InputDecoration(
                hintText: _selectedProstheticType == null
                    ? 'Önce protez türü seçin'
                    : _availableProducts.isEmpty
                        ? 'Bu tür için ürün bulunamadı'
                        : 'Ürün seçin',
              ),
              items: _availableProducts
                  .map(
                    (product) => DropdownMenuItem(
                      value: product,
                      child: Text(
                        product.unitPrice == null
                            ? '${product.name} · Fiyat tanımsız'
                            : product.name,
                      ),
                    ),
                  )
                  .toList(),
              onChanged: (_selectedProstheticType == null ||
                      _availableProducts.isEmpty)
                  ? null
                  : (val) {
                      setState(() => _selectedProduct = val);
                      _refreshProductsAndPrice();
                    },
              validator: (val) {
                if (_availableProducts.isNotEmpty && val == null) {
                  return 'Lütfen ürün seçin';
                }
                return null;
              },
            ),
            if (_productAvailabilityMessage != null) ...[
              const SizedBox(height: 8),
              _InlineInfoBanner(
                message: _productAvailabilityMessage!,
                tone:
                    _hasMissingProductForType || _hasSelectedProductWithoutPrice
                        ? _InfoBannerTone.warning
                        : _InfoBannerTone.info,
              ),
            ],
            if (_selectedProduct?.description?.trim().isNotEmpty == true) ...[
              const SizedBox(height: 8),
              _ProductDescriptionCard(product: _selectedProduct!),
            ],
            const SizedBox(height: 16),

            const _SectionLabel(label: 'İş Tipi'),
            DropdownButtonFormField<JobWorkflowType>(
              initialValue: _selectedWorkflowType,
              decoration: const InputDecoration(
                hintText: 'İş tipi seçin',
              ),
              items: JobWorkflowType.values
                  .map(
                    (type) => DropdownMenuItem(
                      value: type,
                      child: Text(type.label),
                    ),
                  )
                  .toList(),
              onChanged: (val) => setState(() => _selectedWorkflowType = val),
              validator: (val) => val == null ? 'Lütfen iş tipi seçin' : null,
            ),
            // Price preview
            if (_priceLoading)
              const Padding(
                padding: EdgeInsets.only(top: 8),
                child: Row(children: [
                  SizedBox(
                      width: 14,
                      height: 14,
                      child: CircularProgressIndicator(strokeWidth: 1.5)),
                  SizedBox(width: 8),
                  Text('Fiyat yükleniyor...',
                      style:
                          TextStyle(fontSize: 12, color: AppColors.textMuted)),
                ]),
              )
            else if (_labProduct != null && _effectivePrice != null) ...[
              const SizedBox(height: 8),
              _PricePreviewChip(
                product: _labProduct!,
                prostheticType: _selectedProstheticType,
                breakdown: _pricingBreakdown,
                effectivePrice: _effectivePrice!,
              ),
            ],
            const SizedBox(height: 12),

            // Prova flag
            _ProvaToggle(
              value: _provaRequired,
              prostheticType: _selectedProstheticType,
              workflowType: _selectedWorkflowType,
              optionalSteps: _selectedLab != null
                  ? Tenant.fromJson(_selectedLab!).workflowOverrideSteps
                  : const [],
              onChanged: (v) => setState(() => _provaRequired = v),
            ),
            const SizedBox(height: 16),

            // Teeth selection
            _SectionLabel(
              label: 'Dişler * (${_selectedTeeth.length} seçili)',
            ),
            const SizedBox(height: 6),
            // Bulk select row
            _TeethBulkBar(
              selectedTeeth: _selectedTeeth,
              onSelectAll: () {
                setState(() {
                  _selectedTeeth.addAll([
                    for (int i = 11; i <= 18; i++) i,
                    for (int i = 21; i <= 28; i++) i,
                    for (int i = 31; i <= 38; i++) i,
                    for (int i = 41; i <= 48; i++) i,
                  ]);
                });
                _refreshProductsAndPrice();
              },
              onSelectUpper: () {
                setState(() {
                  final upper = {
                    ...[for (int i = 11; i <= 18; i++) i],
                    ...[for (int i = 21; i <= 28; i++) i]
                  };
                  if (upper.every(_selectedTeeth.contains)) {
                    _selectedTeeth.removeAll(upper);
                  } else {
                    _selectedTeeth.addAll(upper);
                  }
                });
                _refreshProductsAndPrice();
              },
              onSelectLower: () {
                setState(() {
                  final lower = {
                    ...[for (int i = 31; i <= 38; i++) i],
                    ...[for (int i = 41; i <= 48; i++) i]
                  };
                  if (lower.every(_selectedTeeth.contains)) {
                    _selectedTeeth.removeAll(lower);
                  } else {
                    _selectedTeeth.addAll(lower);
                  }
                });
                _refreshProductsAndPrice();
              },
              onClear: () {
                setState(() => _selectedTeeth.clear());
                _refreshProductsAndPrice();
              },
            ),
            const SizedBox(height: 8),
            _TeethGrid(
              selectedTeeth: _selectedTeeth,
              onToggle: (t) {
                setState(() {
                  if (_selectedTeeth.contains(t)) {
                    _selectedTeeth.remove(t);
                  } else {
                    _selectedTeeth.add(t);
                  }
                });
                _refreshProductsAndPrice();
              },
            ),
            const SizedBox(height: 16),

            // Color (optional)
            const _SectionLabel(label: 'Renk (İsteğe Bağlı)'),
            TextFormField(
              controller: _colorController,
              decoration: const InputDecoration(
                hintText: 'Ör: A2, B3',
              ),
            ),
            const SizedBox(height: 16),

            // Description (optional)
            const _SectionLabel(label: 'Açıklama (İsteğe Bağlı)'),
            TextFormField(
              controller: _descriptionController,
              decoration: const InputDecoration(
                hintText: 'Ek notlar...',
              ),
              minLines: 2,
              maxLines: 4,
            ),
            const SizedBox(height: 16),

            // Due date (optional)
            const _SectionLabel(label: 'Son Tarih (İsteğe Bağlı)'),
            InkWell(
              onTap: _pickDueDate,
              child: InputDecorator(
                decoration: const InputDecoration(
                  suffixIcon: Icon(Icons.calendar_today),
                ),
                child: Text(
                  _dueDate != null
                      ? '${_dueDate!.day.toString().padLeft(2, '0')}.${_dueDate!.month.toString().padLeft(2, '0')}.${_dueDate!.year}  ${_dueDate!.hour.toString().padLeft(2, '0')}:${_dueDate!.minute.toString().padLeft(2, '0')}'
                      : 'Tarih ve saat seçin',
                  style: _dueDate != null
                      ? null
                      : TextStyle(
                          color: Theme.of(context).colorScheme.onSurfaceVariant,
                        ),
                ),
              ),
            ),
            const SizedBox(height: 16),

            // File attachments (optional)
            const _SectionLabel(label: 'Dosya Ekle (İsteğe Bağlı)'),
            _FilePicker(
              files: _pendingFiles,
              onAdd: () async {
                final result = await FilePicker.platform.pickFiles(
                  allowMultiple: true,
                  withData: true,
                );
                if (result != null) {
                  setState(() => _pendingFiles.addAll(result.files));
                }
              },
              onRemove: (i) => setState(() => _pendingFiles.removeAt(i)),
            ),
            const SizedBox(height: 24),

            // Submit button
            if (_isSubmitting)
              const Center(child: CircularProgressIndicator())
            else
              FilledButton.icon(
                onPressed: _canSubmitJob ? _submit : null,
                icon: const Icon(Icons.check),
                label: const Text('İş Oluştur'),
                style: FilledButton.styleFrom(
                  minimumSize: const Size(double.infinity, 52),
                ),
              ),
            const SizedBox(height: 24),
          ],
        ),
      ),
    );
  }
}

enum _InfoBannerTone { info, warning }

class _InlineInfoBanner extends StatelessWidget {
  const _InlineInfoBanner({
    required this.message,
    required this.tone,
  });

  final String message;
  final _InfoBannerTone tone;

  @override
  Widget build(BuildContext context) {
    final isWarning = tone == _InfoBannerTone.warning;
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
      decoration: BoxDecoration(
        color: isWarning ? AppColors.pendingBg : AppColors.surfaceVariant,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(
          color: isWarning ? AppColors.pending : AppColors.border,
        ),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Icon(
            isWarning
                ? Icons.warning_amber_rounded
                : Icons.info_outline_rounded,
            size: 18,
            color: isWarning ? AppColors.pending : AppColors.textSecondary,
          ),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              message,
              style: TextStyle(
                fontSize: 12,
                color: isWarning ? AppColors.pending : AppColors.textSecondary,
                fontWeight: isWarning ? FontWeight.w600 : FontWeight.w500,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _TeethBulkBar extends StatelessWidget {
  const _TeethBulkBar({
    required this.selectedTeeth,
    required this.onSelectAll,
    required this.onSelectUpper,
    required this.onSelectLower,
    required this.onClear,
  });

  final Set<int> selectedTeeth;
  final VoidCallback onSelectAll;
  final VoidCallback onSelectUpper;
  final VoidCallback onSelectLower;
  final VoidCallback onClear;

  bool _allUpperSelected() {
    final upper = [
      for (int i = 11; i <= 18; i++) i,
      for (int i = 21; i <= 28; i++) i
    ];
    return upper.every(selectedTeeth.contains);
  }

  bool _allLowerSelected() {
    final lower = [
      for (int i = 31; i <= 38; i++) i,
      for (int i = 41; i <= 48; i++) i
    ];
    return lower.every(selectedTeeth.contains);
  }

  @override
  Widget build(BuildContext context) {
    final allSelected = _allUpperSelected() && _allLowerSelected();
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Row(
        children: [
          _BulkChip(
            label: 'Tüm Dişler',
            active: allSelected,
            onTap: allSelected ? onClear : onSelectAll,
            icon: Icons.select_all_rounded,
          ),
          const SizedBox(width: 6),
          _BulkChip(
            label: 'Üst Çene',
            active: _allUpperSelected(),
            onTap: onSelectUpper,
            icon: Icons.arrow_upward_rounded,
          ),
          const SizedBox(width: 6),
          _BulkChip(
            label: 'Alt Çene',
            active: _allLowerSelected(),
            onTap: onSelectLower,
            icon: Icons.arrow_downward_rounded,
          ),
          const SizedBox(width: 6),
          if (selectedTeeth.isNotEmpty)
            _BulkChip(
              label: 'Temizle',
              active: false,
              onTap: onClear,
              icon: Icons.clear_rounded,
              destructive: true,
            ),
        ],
      ),
    );
  }
}

class _BulkChip extends StatelessWidget {
  const _BulkChip({
    required this.label,
    required this.active,
    required this.onTap,
    required this.icon,
    this.destructive = false,
  });

  final String label;
  final bool active;
  final VoidCallback onTap;
  final IconData icon;
  final bool destructive;

  @override
  Widget build(BuildContext context) {
    final color = destructive
        ? AppColors.cancelled
        : active
            ? AppColors.accent
            : AppColors.textSecondary;
    final bg = destructive
        ? AppColors.cancelledBg
        : active
            ? AppColors.inProgressBg
            : AppColors.surfaceVariant;

    return GestureDetector(
      onTap: onTap,
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 120),
        padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
        decoration: BoxDecoration(
          color: bg,
          borderRadius: BorderRadius.circular(20),
          border: Border.all(
            color: active && !destructive ? AppColors.accent : AppColors.border,
          ),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(icon, size: 14, color: color),
            const SizedBox(width: 4),
            Text(
              label,
              style: TextStyle(
                  fontSize: 12, fontWeight: FontWeight.w600, color: color),
            ),
          ],
        ),
      ),
    );
  }
}

class _TeethGrid extends StatelessWidget {
  const _TeethGrid({
    required this.selectedTeeth,
    required this.onToggle,
  });

  final Set<int> selectedTeeth;
  final ValueChanged<int> onToggle;

  @override
  Widget build(BuildContext context) {
    // Upper jaw: 18-11, 21-28
    // Lower jaw: 48-41, 31-38
    final upperRight = List.generate(8, (i) => 18 - i); // 18..11
    final upperLeft = List.generate(8, (i) => 21 + i); // 21..28
    final lowerRight = List.generate(8, (i) => 48 - i); // 48..41
    final lowerLeft = List.generate(8, (i) => 31 + i); // 31..38

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Upper jaw label
        Text('Üst Çene',
            style: Theme.of(context).textTheme.bodySmall?.copyWith(
                  color: Theme.of(context).colorScheme.onSurfaceVariant,
                )),
        const SizedBox(height: 4),
        Row(
          children: [
            ...upperRight.map((t) => _ToothButton(
                  tooth: t,
                  selected: selectedTeeth.contains(t),
                  onTap: () => onToggle(t),
                )),
            const VerticalDivider(width: 8),
            ...upperLeft.map((t) => _ToothButton(
                  tooth: t,
                  selected: selectedTeeth.contains(t),
                  onTap: () => onToggle(t),
                )),
          ],
        ),
        const SizedBox(height: 8),
        // Lower jaw
        Text('Alt Çene',
            style: Theme.of(context).textTheme.bodySmall?.copyWith(
                  color: Theme.of(context).colorScheme.onSurfaceVariant,
                )),
        const SizedBox(height: 4),
        Row(
          children: [
            ...lowerRight.map((t) => _ToothButton(
                  tooth: t,
                  selected: selectedTeeth.contains(t),
                  onTap: () => onToggle(t),
                )),
            const VerticalDivider(width: 8),
            ...lowerLeft.map((t) => _ToothButton(
                  tooth: t,
                  selected: selectedTeeth.contains(t),
                  onTap: () => onToggle(t),
                )),
          ],
        ),
      ],
    );
  }
}

class _ToothButton extends StatelessWidget {
  const _ToothButton({
    required this.tooth,
    required this.selected,
    required this.onTap,
  });

  final int tooth;
  final bool selected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: GestureDetector(
        onTap: onTap,
        child: Container(
          margin: const EdgeInsets.all(1.5),
          height: 36,
          decoration: BoxDecoration(
            color: selected
                ? Theme.of(context).colorScheme.primary
                : Theme.of(context).colorScheme.surfaceContainerHighest,
            borderRadius: BorderRadius.circular(4),
          ),
          child: Center(
            child: Text(
              '$tooth',
              style: TextStyle(
                fontSize: 9,
                fontWeight: FontWeight.bold,
                color: selected
                    ? Theme.of(context).colorScheme.onPrimary
                    : Theme.of(context).colorScheme.onSurfaceVariant,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class _FilePicker extends StatelessWidget {
  const _FilePicker({
    required this.files,
    required this.onAdd,
    required this.onRemove,
  });

  final List<PlatformFile> files;
  final VoidCallback onAdd;
  final void Function(int index) onRemove;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (files.isNotEmpty) ...[
          ...files.asMap().entries.map((e) {
            final i = e.key;
            final f = e.value;
            return Container(
              margin: const EdgeInsets.only(bottom: 6),
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
              decoration: BoxDecoration(
                color: AppColors.surfaceVariant,
                borderRadius: BorderRadius.circular(10),
                border: Border.all(color: AppColors.border),
              ),
              child: Row(
                children: [
                  const Icon(Icons.attach_file,
                      size: 16, color: AppColors.textSecondary),
                  const SizedBox(width: 8),
                  Expanded(
                    child: Text(
                      f.name,
                      style: const TextStyle(
                          fontSize: 13, color: AppColors.textPrimary),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  Text(
                    _formatSize(f.size),
                    style: const TextStyle(
                        fontSize: 11, color: AppColors.textMuted),
                  ),
                  const SizedBox(width: 4),
                  GestureDetector(
                    onTap: () => onRemove(i),
                    child: const Icon(Icons.close,
                        size: 16, color: AppColors.textSecondary),
                  ),
                ],
              ),
            );
          }),
          const SizedBox(height: 4),
        ],
        OutlinedButton.icon(
          onPressed: onAdd,
          icon: const Icon(Icons.upload_file_outlined, size: 18),
          label: const Text('Dosya Seç'),
          style: OutlinedButton.styleFrom(
            foregroundColor: AppColors.accent,
            side: const BorderSide(color: AppColors.accent),
          ),
        ),
      ],
    );
  }

  String _formatSize(int bytes) {
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
  }
}

class _PricePreviewChip extends StatelessWidget {
  const _PricePreviewChip({
    required this.product,
    required this.effectivePrice,
    this.prostheticType,
    this.breakdown,
  });

  final ProstheticProduct product;
  final double effectivePrice;
  final ProstheticType? prostheticType;
  final PricingBreakdown? breakdown;

  @override
  Widget build(BuildContext context) {
    final currency = product.currency ?? 'TRY';
    final unitPrice = product.unitPrice!;
    final hasDiscount = (breakdown?.discountAmount ?? 0) > 0.01;
    final units = breakdown?.billableUnits ?? 1;
    final unitLabel = prostheticType != null
        ? PricingService.instance.unitLabelForType(prostheticType!)
        : 'adet';
    final baseAmount = breakdown?.baseAmount ?? unitPrice;

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      decoration: BoxDecoration(
        color: AppColors.successBg,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: AppColors.success.withValues(alpha: 0.25)),
      ),
      child: Row(
        children: [
          const Icon(Icons.sell_outlined, size: 16, color: AppColors.success),
          const SizedBox(width: 8),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '${product.name} — ${effectivePrice.toStringAsFixed(2)} $currency',
                  style: const TextStyle(
                      fontSize: 13,
                      fontWeight: FontWeight.w700,
                      color: AppColors.success),
                ),
                Text(
                  '${unitPrice.toStringAsFixed(2)} $currency x $units $unitLabel',
                  style: TextStyle(
                      fontSize: 11,
                      color: AppColors.success.withValues(alpha: 0.75)),
                ),
                if (hasDiscount)
                  Text(
                    'Liste: ${baseAmount.toStringAsFixed(2)} $currency · İndirim uygulandı',
                    style: TextStyle(
                        fontSize: 11,
                        color: AppColors.success.withValues(alpha: 0.75)),
                  )
                else
                  Text(
                    'Liste fiyatı · İndirim yok',
                    style: TextStyle(
                        fontSize: 11,
                        color: AppColors.success.withValues(alpha: 0.75)),
                  ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _ProductDescriptionCard extends StatelessWidget {
  const _ProductDescriptionCard({required this.product});

  final ProstheticProduct product;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
      decoration: BoxDecoration(
        color: AppColors.surfaceVariant,
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: AppColors.border),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Icon(Icons.notes_rounded, size: 16, color: AppColors.textMuted),
          const SizedBox(width: 8),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  'Ürün açıklaması',
                  style: TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w700,
                    color: AppColors.textSecondary,
                  ),
                ),
                const SizedBox(height: 3),
                Text(
                  product.description!.trim(),
                  style: const TextStyle(
                    fontSize: 12,
                    height: 1.35,
                    color: AppColors.textPrimary,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _SectionLabel extends StatelessWidget {
  const _SectionLabel({required this.label});
  final String label;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 6),
      child: Text(
        label,
        style: Theme.of(context).textTheme.bodyMedium?.copyWith(
              fontWeight: FontWeight.w600,
            ),
      ),
    );
  }
}

class _ProvaToggle extends StatelessWidget {
  const _ProvaToggle({
    required this.value,
    required this.onChanged,
    required this.optionalSteps,
    this.prostheticType,
    this.workflowType,
  });

  final bool value;
  final ValueChanged<bool> onChanged;
  final ProstheticType? prostheticType;
  final JobWorkflowType? workflowType;
  final List<JobStep> optionalSteps;

  @override
  Widget build(BuildContext context) {
    final preset = prostheticType != null
        ? buildJobWorkflowPreset(
            prostheticType: prostheticType!,
            workflowType: workflowType,
            provaRequired: value,
            optionalSteps: optionalSteps,
          )
        : null;
    final steps = preset?.steps ?? <JobStep>[];

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
      decoration: BoxDecoration(
        color: value ? AppColors.inProgressBg : AppColors.surfaceVariant,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(
          color: value
              ? AppColors.inProgress.withValues(alpha: 0.3)
              : AppColors.border,
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Icon(
                value ? Icons.swap_horiz_rounded : Icons.straighten_rounded,
                size: 20,
                color: value ? AppColors.inProgress : AppColors.textSecondary,
              ),
              const SizedBox(width: 10),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      value ? 'Provalı İş' : 'Provasız İş',
                      style: TextStyle(
                        fontWeight: FontWeight.w700,
                        color: value
                            ? AppColors.inProgress
                            : AppColors.textPrimary,
                        fontSize: 14,
                      ),
                    ),
                    Text(
                      preset?.title ??
                          (value
                              ? 'Lab her adımda klinik onayı bekler'
                              : 'Lab doğrudan üretip teslime gönderir'),
                      style: const TextStyle(
                          fontSize: 12, color: AppColors.textSecondary),
                    ),
                  ],
                ),
              ),
              Switch(
                value: value,
                onChanged: onChanged,
                activeThumbColor: AppColors.inProgress,
              ),
            ],
          ),
          if (steps.isNotEmpty) ...[
            const SizedBox(height: 8),
            if (preset != null)
              Padding(
                padding: const EdgeInsets.only(bottom: 8),
                child: Text(
                  preset.summary,
                  style: const TextStyle(
                    fontSize: 12,
                    color: AppColors.textSecondary,
                  ),
                ),
              ),
            Wrap(
              spacing: 6,
              children: steps
                  .map((s) => Container(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 8, vertical: 3),
                        decoration: BoxDecoration(
                          color: AppColors.surface,
                          borderRadius: BorderRadius.circular(6),
                          border: Border.all(color: AppColors.border),
                        ),
                        child: Text(
                          s.label,
                          style: const TextStyle(
                              fontSize: 11, color: AppColors.textSecondary),
                        ),
                      ))
                  .toList(),
            ),
          ],
        ],
      ),
    );
  }
}
