import 'package:date_picker_timeline/date_picker_timeline.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MedicineReminderApp());
}

class MedicineReminderApp extends StatelessWidget {
  const MedicineReminderApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Medicine Reminder',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: const MedicineListScreen(),
    );
  }
}

class MedicineListScreen extends StatefulWidget {
  const MedicineListScreen({super.key});

  @override
  _MedicineListScreenState createState() => _MedicineListScreenState();
}

class _MedicineListScreenState extends State<MedicineListScreen> {
  DateTime _selectedDate = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Medicine List'),
      ),
      body: Column(
        children: [
          DatePicker(
            DateTime.now(),
            selectionColor: Colors.pink,
            daysCount: 10,
            onDateChange: (date) {
              setState(() {
                _selectedDate = date;
                print(date);
              });
            },
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Row(
              children: [
                const Text('Selected Date:'),
                const SizedBox(width: 10),
                TextButton(
                  onPressed: () async {
                    final DateTime? pickedDate = await showDatePicker(
                      context: context,
                      initialDate: _selectedDate,
                      firstDate: DateTime(2020),
                      lastDate: DateTime(2100),
                    );
                    if (pickedDate != null && pickedDate != _selectedDate) {
                      setState(() {
                        _selectedDate = pickedDate;
                        print(pickedDate);
                      });
                    }
                  },
                  child: Text(
                    '${_selectedDate.year}-${_selectedDate.month}-${_selectedDate.day}',
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: FutureBuilder<List<Medicine>>(
              future: DatabaseHelper().getMedicinesForDate(_selectedDate),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const Center(child: CircularProgressIndicator());
                } else if (snapshot.hasError) {
                  return Center(child: Text('Error: ${snapshot.error}'));
                } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
                  return const Center(
                      child: Text('No Medicines Found for Selected Date'));
                } else {
                  return ListView.builder(
                    itemCount: snapshot.data!.length,
                    itemBuilder: (context, index) {
                      Medicine medicine = snapshot.data![index];
                      return ListTile(
                        title: Text(medicine.name),
                        subtitle: Text(
                            'Dosage: ${medicine.dosage}\nFrequency: ${medicine.frequency}\nDuration: ${medicine.durationInDays} days'),
                      );
                    },
                  );
                }
              },
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const AddMedicineScreen()),
          );
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

class AddMedicineScreen extends StatefulWidget {
  const AddMedicineScreen({Key? key}) : super(key: key);

  @override
  _AddMedicineScreenState createState() => _AddMedicineScreenState();
}

class _AddMedicineScreenState extends State<AddMedicineScreen> {
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _dosageController = TextEditingController();
  final TextEditingController _frequencyController = TextEditingController();
  final TextEditingController _durationController = TextEditingController();
  DateTime _selectedDate = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Add Medicine'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextField(
              controller: _nameController,
              decoration: const InputDecoration(labelText: 'Name'),
            ),
            TextField(
              controller: _dosageController,
              decoration: const InputDecoration(labelText: 'Dosage'),
            ),
            TextField(
              controller: _frequencyController,
              decoration: const InputDecoration(labelText: 'Frequency'),
            ),
            TextField(
              controller: _durationController,
              decoration:
                  const InputDecoration(labelText: 'Duration (in days)'),
              keyboardType: TextInputType.number,
            ),
            const SizedBox(height: 16.0),
            DatePicker(
              DateTime.now(),
              selectionColor: Colors.pink,
              daysCount: 10,
              onDateChange: (date) {
                setState(() {
                  _selectedDate = date;
                });
              },
            ),
            const SizedBox(height: 16.0),
            ElevatedButton(
              onPressed: () {
                _addMedicine();
                Navigator.pop(context); // Go back to the previous screen
              },
              child: const Text('Add Medicine'),
            ),
          ],
        ),
      ),
    );
  }

  void _addMedicine() {
    String name = _nameController.text;
    String dosage = _dosageController.text;
    String frequency = _frequencyController.text;
    int duration = int.tryParse(_durationController.text) ?? 0;

    if (name.isNotEmpty &&
        dosage.isNotEmpty &&
        frequency.isNotEmpty &&
        duration > 0) {
      Medicine newMedicine = Medicine(
        name: name,
        dosage: dosage,
        frequency: frequency,
        reminderTime:
            _selectedDate, // Set the selected date as the reminder time
        durationInDays: duration,
      );

      // Call the method to insert the medicine into the database
      DatabaseHelper().insertMedicine(newMedicine);
    }
  }
}

class Medicine {
  final String name;
  final String dosage;
  final String frequency;
  final DateTime reminderTime;
  final int durationInDays;

  Medicine({
    required this.name,
    required this.dosage,
    required this.frequency,
    required this.reminderTime,
    required this.durationInDays,
  });

  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'dosage': dosage,
      'frequency': frequency,
      'reminderTime': reminderTime.millisecondsSinceEpoch,
      'durationInDays': durationInDays,
    };
  }
}

class DatabaseHelper {
  static Database? _database;

  Future<Database> get database async {
    if (_database != null) return _database!;

    _database = await initDatabase();
    return _database!;
  }

  Future<Database> initDatabase() async {
    String path = join(await getDatabasesPath(), 'medicine.db');
    return await openDatabase(path, version: 1, onCreate: _createDb);
  }

  Future<void> _createDb(Database db, int version) async {
    await db.execute('''
      CREATE TABLE medicines(
        id INTEGER PRIMARY KEY,
        name TEXT,
        dosage TEXT,
        frequency TEXT,
        reminderTime INTEGER,
        durationInDays INTEGER
      )
    ''');
  }

  Future<void> insertMedicine(Medicine medicine) async {
    Database db = await database;
    await db.insert('medicines', medicine.toMap());
  }

  Future<List<Medicine>> getMedicines() async {
    Database db = await database;
    List<Map<String, dynamic>> maps = await db.query('medicines');
    return List.generate(maps.length, (index) {
      return Medicine(
        name: maps[index]['name'],
        dosage: maps[index]['dosage'],
        frequency: maps[index]['frequency'],
        reminderTime:
            DateTime.fromMillisecondsSinceEpoch(maps[index]['reminderTime']),
        durationInDays: maps[index]['durationInDays'],
      );
    });
  }

  Future<List<Medicine>> getMedicinesForDate(DateTime date) async {
    Database db = await database;
    final startOfDay = DateTime(date.year, date.month, date.day);
    final endOfDay = DateTime(date.year, date.month, date.day + 1);
    List<Map<String, dynamic>> maps = await db.query(
      'medicines',
      where: 'reminderTime >= ? AND reminderTime < ?',
      whereArgs: [
        startOfDay.millisecondsSinceEpoch,
        endOfDay.millisecondsSinceEpoch
      ],
    );
    return List.generate(maps.length, (index) {
      return Medicine(
        name: maps[index]['name'],
        dosage: maps[index]['dosage'],
        frequency: maps[index]['frequency'],
        reminderTime:
            DateTime.fromMillisecondsSinceEpoch(maps[index]['reminderTime']),
        durationInDays: maps[index]['durationInDays'],
      );
    });
  }
}