import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';

import '../../../core/database/database.dart';
import '../../../core/providers/database_provider.dart';
import '../../../l10n/app_localizations.dart';
import '../domain/effort_level.dart';
import '../domain/frequency.dart';
import 'task_history_sheet.dart';
import 'task_providers.dart';

/// Full-screen form for task creation and editing.
///
/// Pass [roomId] for create mode, or [taskId] for edit mode.
class TaskFormScreen extends ConsumerStatefulWidget {
  final int? roomId;
  final int? taskId;

  const TaskFormScreen({super.key, this.roomId, this.taskId});

  bool get isEditing => taskId != null;

  @override
  ConsumerState<TaskFormScreen> createState() => _TaskFormScreenState();
}

class _TaskFormScreenState extends ConsumerState<TaskFormScreen> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _descriptionController = TextEditingController();
  final _customIntervalController = TextEditingController(text: '2');

  FrequencyInterval? _selectedPreset;
  bool _isCustomFrequency = false;
  _CustomUnit _customUnit = _CustomUnit.days;
  EffortLevel _effortLevel = EffortLevel.medium;
  DateTime _dueDate = DateTime.now();
  Task? _existingTask;
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _selectedPreset = FrequencyInterval.presets[3]; // Default: weekly
    _dueDate = _dateOnly(DateTime.now());
    if (widget.isEditing) {
      _loadExistingTask();
    }
  }

  Future<void> _loadExistingTask() async {
    final db = ref.read(appDatabaseProvider);
    final task = await (db.select(db.tasks)
          ..where((t) => t.id.equals(widget.taskId!)))
        .getSingle();

    setState(() {
      _existingTask = task;
      _nameController.text = task.name;
      _descriptionController.text = task.description ?? '';
      _effortLevel = task.effortLevel;
      _dueDate = task.nextDueDate;

      // Find matching preset
      _selectedPreset = null;
      _isCustomFrequency = true;
      for (final preset in FrequencyInterval.presets) {
        if (preset.intervalType == task.intervalType &&
            preset.days == task.intervalDays) {
          _selectedPreset = preset;
          _isCustomFrequency = false;
          break;
        }
      }

      if (_isCustomFrequency) {
        // Determine custom unit from stored interval
        switch (task.intervalType) {
          case IntervalType.everyNMonths:
            _customUnit = _CustomUnit.months;
            _customIntervalController.text = task.intervalDays.toString();
          case IntervalType.monthly:
            _customUnit = _CustomUnit.months;
            _customIntervalController.text = '1';
          case IntervalType.weekly:
            _customUnit = _CustomUnit.weeks;
            _customIntervalController.text = '1';
          case IntervalType.biweekly:
            _customUnit = _CustomUnit.weeks;
            _customIntervalController.text = '2';
          default:
            _customUnit = _CustomUnit.days;
            _customIntervalController.text = task.intervalDays.toString();
        }
      }
    });
  }

  @override
  void dispose() {
    _nameController.dispose();
    _descriptionController.dispose();
    _customIntervalController.dispose();
    super.dispose();
  }

  int get _roomId => widget.roomId ?? _existingTask!.roomId;

  static DateTime _dateOnly(DateTime dt) => DateTime(dt.year, dt.month, dt.day);

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context);
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(
          widget.isEditing ? l10n.taskFormEditTitle : l10n.taskFormCreateTitle,
        ),
        actions: [
          IconButton(
            onPressed: _isLoading ? null : _onSave,
            icon: const Icon(Icons.check),
          ),
        ],
      ),
      body: Form(
        key: _formKey,
        child: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            // Name field (required, autofocus)
            TextFormField(
              controller: _nameController,
              autofocus: !widget.isEditing,
              maxLength: 200,
              decoration: InputDecoration(
                labelText: l10n.taskFormNameLabel,
                hintText: l10n.taskFormNameHint,
              ),
              validator: (value) {
                if (value == null || value.trim().isEmpty) {
                  return l10n.taskFormNameRequired;
                }
                return null;
              },
            ),
            const SizedBox(height: 16),

            // Frequency selector
            Text(
              l10n.taskFormFrequencyLabel,
              style: theme.textTheme.titleSmall,
            ),
            const SizedBox(height: 8),
            _buildFrequencySelector(l10n, theme),
            const SizedBox(height: 16),

            // Effort selector
            Text(
              l10n.taskFormEffortLabel,
              style: theme.textTheme.titleSmall,
            ),
            const SizedBox(height: 8),
            _buildEffortSelector(),
            const SizedBox(height: 16),

            // Description (optional)
            TextFormField(
              controller: _descriptionController,
              maxLines: 3,
              decoration: InputDecoration(
                labelText: l10n.taskFormDescriptionLabel,
              ),
            ),
            const SizedBox(height: 16),

            // Initial due date
            Text(
              l10n.taskFormDueDateLabel,
              style: theme.textTheme.titleSmall,
            ),
            const SizedBox(height: 8),
            _buildDueDatePicker(theme),

            // History section (edit mode only)
            if (widget.isEditing) ...[
              const SizedBox(height: 24),
              const Divider(),
              ListTile(
                leading: const Icon(Icons.history),
                title: Text(l10n.taskHistoryTitle),
                trailing: const Icon(Icons.chevron_right),
                onTap: () => showTaskHistorySheet(
                  context: context,
                  taskId: widget.taskId!,
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildFrequencySelector(AppLocalizations l10n, ThemeData theme) {
    final items = <Widget>[];

    // Preset intervals
    for (final preset in FrequencyInterval.presets) {
      items.add(
        ChoiceChip(
          label: Text(preset.label()),
          selected: !_isCustomFrequency && _selectedPreset == preset,
          onSelected: (selected) {
            if (selected) {
              setState(() {
                _selectedPreset = preset;
                _isCustomFrequency = false;
              });
            }
          },
        ),
      );
    }

    // Custom option
    items.add(
      ChoiceChip(
        label: Text(l10n.taskFormFrequencyCustom),
        selected: _isCustomFrequency,
        onSelected: (selected) {
          if (selected) {
            setState(() {
              _isCustomFrequency = true;
              _selectedPreset = null;
            });
          }
        },
      ),
    );

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Wrap(
          spacing: 8,
          runSpacing: 4,
          children: items,
        ),
        if (_isCustomFrequency) ...[
          const SizedBox(height: 12),
          _buildCustomFrequencyInput(l10n, theme),
        ],
      ],
    );
  }

  Widget _buildCustomFrequencyInput(AppLocalizations l10n, ThemeData theme) {
    return Row(
      children: [
        Text(
          l10n.taskFormFrequencyEvery,
          style: theme.textTheme.bodyLarge,
        ),
        const SizedBox(width: 8),
        SizedBox(
          width: 60,
          child: TextFormField(
            controller: _customIntervalController,
            keyboardType: TextInputType.number,
            inputFormatters: [FilteringTextInputFormatter.digitsOnly],
            textAlign: TextAlign.center,
            decoration: const InputDecoration(
              contentPadding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
            ),
          ),
        ),
        const SizedBox(width: 8),
        Expanded(
          child: SegmentedButton<_CustomUnit>(
            segments: [
              ButtonSegment(
                value: _CustomUnit.days,
                label: Text(l10n.taskFormFrequencyUnitDays),
              ),
              ButtonSegment(
                value: _CustomUnit.weeks,
                label: Text(l10n.taskFormFrequencyUnitWeeks),
              ),
              ButtonSegment(
                value: _CustomUnit.months,
                label: Text(l10n.taskFormFrequencyUnitMonths),
              ),
            ],
            selected: {_customUnit},
            onSelectionChanged: (newSelection) {
              setState(() {
                _customUnit = newSelection.first;
              });
            },
          ),
        ),
      ],
    );
  }

  Widget _buildEffortSelector() {
    return SegmentedButton<EffortLevel>(
      segments: EffortLevel.values
          .map((e) => ButtonSegment(
                value: e,
                label: Text(e.label()),
              ))
          .toList(),
      selected: {_effortLevel},
      onSelectionChanged: (newSelection) {
        setState(() {
          _effortLevel = newSelection.first;
        });
      },
    );
  }

  Widget _buildDueDatePicker(ThemeData theme) {
    final dateFormat = DateFormat('dd.MM.yyyy');
    return InkWell(
      onTap: _pickDueDate,
      borderRadius: BorderRadius.circular(8),
      child: InputDecorator(
        decoration: const InputDecoration(
          suffixIcon: Icon(Icons.calendar_today),
        ),
        child: Text(
          dateFormat.format(_dueDate),
          style: theme.textTheme.bodyLarge,
        ),
      ),
    );
  }

  Future<void> _pickDueDate() async {
    final picked = await showDatePicker(
      context: context,
      initialDate: _dueDate,
      firstDate: DateTime(2020),
      lastDate: DateTime(2100),
      locale: const Locale('de'),
    );
    if (picked != null) {
      setState(() {
        _dueDate = _dateOnly(picked);
      });
    }
  }

  /// Resolve the frequency from either selected preset or custom input.
  ({IntervalType type, int days, int? anchorDay}) _resolveFrequency() {
    if (!_isCustomFrequency && _selectedPreset != null) {
      final preset = _selectedPreset!;
      // For calendar-anchored intervals, set anchorDay to due date's day
      int? anchorDay;
      if (_isCalendarAnchored(preset.intervalType)) {
        anchorDay = _dueDate.day;
      }
      return (
        type: preset.intervalType,
        days: preset.days,
        anchorDay: anchorDay,
      );
    }

    // Custom frequency
    final number = int.tryParse(_customIntervalController.text) ?? 1;
    switch (_customUnit) {
      case _CustomUnit.days:
        return (
          type: IntervalType.everyNDays,
          days: number,
          anchorDay: null,
        );
      case _CustomUnit.weeks:
        return (
          type: IntervalType.everyNDays,
          days: number * 7,
          anchorDay: null,
        );
      case _CustomUnit.months:
        return (
          type: IntervalType.everyNMonths,
          days: number,
          anchorDay: _dueDate.day,
        );
    }
  }

  bool _isCalendarAnchored(IntervalType type) {
    return type == IntervalType.monthly ||
        type == IntervalType.everyNMonths ||
        type == IntervalType.quarterly ||
        type == IntervalType.yearly;
  }

  Future<void> _onSave() async {
    if (!_formKey.currentState!.validate()) return;

    setState(() => _isLoading = true);

    try {
      final freq = _resolveFrequency();
      final actions = ref.read(taskActionsProvider.notifier);

      if (widget.isEditing && _existingTask != null) {
        final updatedTask = _existingTask!.copyWith(
          name: _nameController.text.trim(),
          description: Value(_descriptionController.text.trim().isEmpty
              ? null
              : _descriptionController.text.trim()),
          intervalType: freq.type,
          intervalDays: freq.days,
          anchorDay: Value(freq.anchorDay),
          effortLevel: _effortLevel,
          nextDueDate: _dueDate,
        );
        await actions.updateTask(updatedTask);
      } else {
        await actions.createTask(
          roomId: _roomId,
          name: _nameController.text.trim(),
          description: _descriptionController.text.trim().isEmpty
              ? null
              : _descriptionController.text.trim(),
          intervalType: freq.type,
          intervalDays: freq.days,
          anchorDay: freq.anchorDay,
          effortLevel: _effortLevel,
          nextDueDate: _dueDate,
        );
      }

      if (mounted) {
        context.pop();
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }
}

/// Unit options for custom frequency input.
enum _CustomUnit { days, weeks, months }
