import 'dart:convert';
import 'package:sqflite/sqflite.dart';
import 'database_helper.dart';

class AppSettingsRepository {
  static const _kHomeMode = 'home_mode'; // 'invoice_history' or 'dashboard'
  static const _kDashboardStatusEnabled = 'dashboard_status_enabled';
  static const _kDashboardStatusText = 'dashboard_status_text';
  static const _kDashboardMenu = 'dashboard_menu';
  static const _kDashboardHistoryUnlocked = 'dashboard_history_unlocked';
  static const _kTheme = 'app_theme'; // light / dark / system
  static const _kSummaryTheme = 'summary_theme'; // 'white' or 'blue'
  static const _kGoogleCalendarEnabled = 'google_calendar_enabled';
  static const _kGoogleCalendarId = 'google_calendar_id';
  static const _kGoogleCalendarAccount = 'google_calendar_account';
  static const _kGrossProfitEnabled = 'gross_profit_enabled';
  static const _kGrossProfitToggleVisible = 'gross_profit_toggle_visible';
  static const _kGrossProfitIncludeProvisional = 'gross_profit_include_provisional';
  static const _kSalesEntryCashModeDefault = 'sales_entry_cash_mode_default';
  static const _kSalesEntryShowGross = 'sales_entry_show_gross';

  final DatabaseHelper _dbHelper = DatabaseHelper();

  Future<void> _ensureTable() async {
    final db = await _dbHelper.database;
    await db.execute('''
      CREATE TABLE IF NOT EXISTS app_settings (
        key TEXT PRIMARY KEY,
        value TEXT
      )
    ''');
  }

  Future<String> getHomeMode() async {
    final v = await _getValue(_kHomeMode);
    return v ?? 'invoice_history';
  }

  Future<void> setHomeMode(String mode) async {
    await _setValue(_kHomeMode, mode);
  }

  Future<bool> getDashboardStatusEnabled() async {
    final v = await _getValue(_kDashboardStatusEnabled);
    if (v == null) return true; // デフォルト表示ON
    return v == '1' || v.toLowerCase() == 'true';
  }

  Future<void> setDashboardStatusEnabled(bool enabled) async {
    await _setValue(_kDashboardStatusEnabled, enabled ? '1' : '0');
  }

  Future<String> getDashboardStatusText() async {
    return await _getValue(_kDashboardStatusText) ?? '工事中';
  }

  Future<void> setDashboardStatusText(String text) async {
    await _setValue(_kDashboardStatusText, text);
  }

  Future<List<DashboardMenuItem>> getDashboardMenu() async {
    final raw = await _getValue(_kDashboardMenu);
    if (raw == null || raw.isEmpty) {
      return [DashboardMenuItem(id: 'a2', title: '伝票一覧', route: 'invoice_history', iconName: 'list_alt')];
    }
    try {
      final decoded = jsonDecode(raw);
      if (decoded is List) {
        return decoded.map((e) => DashboardMenuItem.fromJson(e as Map<String, dynamic>)).toList();
      }
    } catch (_) {}
    return [DashboardMenuItem(id: 'a2', title: '伝票一覧', route: 'invoice_history', iconName: 'list_alt')];
  }

  Future<void> setDashboardMenu(List<DashboardMenuItem> items) async {
    final raw = jsonEncode(items.map((e) => e.toJson()).toList());
    await _setValue(_kDashboardMenu, raw);
  }

  Future<bool> getDashboardHistoryUnlocked() async => getBool(_kDashboardHistoryUnlocked, defaultValue: false);
  Future<void> setDashboardHistoryUnlocked(bool unlocked) async => setBool(_kDashboardHistoryUnlocked, unlocked);

  Future<String> getTheme() async => await getString(_kTheme) ?? 'system';
  Future<void> setTheme(String theme) async => setString(_kTheme, theme);

  Future<String> getSummaryTheme() async => await getString(_kSummaryTheme) ?? 'white';
  Future<void> setSummaryTheme(String theme) async => setString(_kSummaryTheme, theme);

  Future<bool> getGoogleCalendarEnabled({bool defaultValue = false}) async {
    return getBool(_kGoogleCalendarEnabled, defaultValue: defaultValue);
  }

  Future<void> setGoogleCalendarEnabled(bool enabled) async {
    await setBool(_kGoogleCalendarEnabled, enabled);
  }

  Future<String?> getGoogleCalendarId() async => getString(_kGoogleCalendarId);

  Future<void> setGoogleCalendarId(String? calendarId) async {
    if (calendarId == null || calendarId.isEmpty) {
      await deleteKey(_kGoogleCalendarId);
    } else {
      await setString(_kGoogleCalendarId, calendarId);
    }
  }

  Future<String?> getGoogleCalendarAccountEmail() async => getString(_kGoogleCalendarAccount);

  Future<void> setGoogleCalendarAccountEmail(String? email) async {
    if (email == null || email.isEmpty) {
      await deleteKey(_kGoogleCalendarAccount);
    } else {
      await setString(_kGoogleCalendarAccount, email);
    }
  }

  Future<void> clearGoogleCalendarSettings() async {
    await setGoogleCalendarEnabled(false);
    await setGoogleCalendarId(null);
    await setGoogleCalendarAccountEmail(null);
  }

  Future<bool> getGrossProfitEnabled({bool defaultValue = true}) async {
    return getBool(_kGrossProfitEnabled, defaultValue: defaultValue);
  }

  Future<void> setGrossProfitEnabled(bool enabled) async {
    await setBool(_kGrossProfitEnabled, enabled);
  }

  Future<bool> getGrossProfitToggleVisible({bool defaultValue = true}) async {
    return getBool(_kGrossProfitToggleVisible, defaultValue: defaultValue);
  }

  Future<void> setGrossProfitToggleVisible(bool visible) async {
    await setBool(_kGrossProfitToggleVisible, visible);
  }

  Future<bool> getGrossProfitIncludeProvisional({bool defaultValue = false}) async {
    return getBool(_kGrossProfitIncludeProvisional, defaultValue: defaultValue);
  }

  Future<void> setGrossProfitIncludeProvisional(bool include) async {
    await setBool(_kGrossProfitIncludeProvisional, include);
  }

  Future<bool> getSalesEntryCashModeDefault({bool defaultValue = false}) async {
    return getBool(_kSalesEntryCashModeDefault, defaultValue: defaultValue);
  }

  Future<void> setSalesEntryCashModeDefault(bool enabled) async {
    await setBool(_kSalesEntryCashModeDefault, enabled);
  }

  Future<bool> getSalesEntryShowGross({bool defaultValue = true}) async {
    return getBool(_kSalesEntryShowGross, defaultValue: defaultValue);
  }

  Future<void> setSalesEntryShowGross(bool display) async {
    await setBool(_kSalesEntryShowGross, display);
  }

  // Generic helpers
  Future<String?> getString(String key) async => _getValue(key);
  Future<void> setString(String key, String value) async => _setValue(key, value);
  Future<void> deleteKey(String key) async => _deleteValue(key);

  Future<bool> getBool(String key, {bool defaultValue = false}) async {
    final v = await _getValue(key);
    if (v == null) return defaultValue;
    return v == '1' || v.toLowerCase() == 'true';
  }

  Future<void> setBool(String key, bool value) async => _setValue(key, value ? '1' : '0');

  Future<String?> _getValue(String key) async {
    await _ensureTable();
    final db = await _dbHelper.database;
    final res = await db.query('app_settings', where: 'key = ?', whereArgs: [key], limit: 1);
    if (res.isEmpty) return null;
    return res.first['value'] as String?;
  }

  Future<void> _setValue(String key, String value) async {
    await _ensureTable();
    final db = await _dbHelper.database;
    await db.insert('app_settings', {'key': key, 'value': value}, conflictAlgorithm: ConflictAlgorithm.replace);
  }

  Future<void> _deleteValue(String key) async {
    await _ensureTable();
    final db = await _dbHelper.database;
    await db.delete('app_settings', where: 'key = ?', whereArgs: [key]);
  }
}

class DashboardMenuItem {
  final String id;
  final String title;
  final String route;
  final String? iconName; // Material icon name
  final String? customIconPath; // optional local file path

  DashboardMenuItem({required this.id, required this.title, required this.route, this.iconName, this.customIconPath});

  DashboardMenuItem copyWith({String? id, String? title, String? route, String? iconName, String? customIconPath}) {
    return DashboardMenuItem(
      id: id ?? this.id,
      title: title ?? this.title,
      route: route ?? this.route,
      iconName: iconName ?? this.iconName,
      customIconPath: customIconPath ?? this.customIconPath,
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'title': title,
        'route': route,
        'iconName': iconName,
        'customIconPath': customIconPath,
      };

  factory DashboardMenuItem.fromJson(Map<String, dynamic> json) {
    return DashboardMenuItem(
      id: json['id'] as String,
      title: json['title'] as String,
      route: json['route'] as String,
      iconName: json['iconName'] as String?,
      customIconPath: json['customIconPath'] as String?,
    );
  }
}
