import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Shield, Bell, User, Smartphone, Sparkles } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { YGroup } from '@tamagui/group';
import { ListItem } from '@tamagui/list-item';
import { SizableText as Text } from '@tamagui/text';
import { Switch } from '@tamagui/switch';
import { MobileShell } from './components/MobileShell';
import { MobileCard, CTAButton, PillBadge } from './components/Primitives';
import { useAuth } from '../auth/context';
import {
  getNotificationPreferences,
  updateNotificationPreferences,
  NotificationPreferences,
} from '../api';
import { getApiErrorMessage } from '../lib/apiError';
import { adminPath, ADMIN_HOME_PATH, ADMIN_PROFILE_ACCOUNT_PATH } from '../constants';
import { useAdminPushSubscription } from './hooks/useAdminPushSubscription';
import { useDevicePermissions } from './hooks/useDevicePermissions';
import { type PermissionStatus, type StorageStatus } from './lib/devicePermissions';
import { useInstallPrompt } from './hooks/useInstallPrompt';
import { getInstallBannerDismissed, setInstallBannerDismissed, shouldShowInstallBanner } from './lib/installBanner';
import { MobileInstallBanner } from './components/MobileInstallBanner';
import { setTourSeen } from './lib/mobileTour';
import { useBackNavigation } from './hooks/useBackNavigation';
import { useOnlineStatus } from './hooks/useOnlineStatus';
import { useAdminTheme } from './theme';

type PreferenceKey = keyof NotificationPreferences;

const AVAILABLE_PREFS: PreferenceKey[] = [
  'photo_thresholds',
  'photo_limits',
  'guest_thresholds',
  'guest_limits',
  'gallery_warnings',
  'gallery_expired',
  'event_thresholds',
  'event_limits',
  'package_expiring',
  'package_expired',
];

export default function MobileSettingsPage() {
  const { t } = useTranslation('management');
  const navigate = useNavigate();
  const { user, logout } = useAuth();
  const { text, muted, border, danger } = useAdminTheme();
  const [preferences, setPreferences] = React.useState<NotificationPreferences>({});
  const [defaults, setDefaults] = React.useState<NotificationPreferences>({});
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);
  const [storageSaving, setStorageSaving] = React.useState(false);
  const [storageError, setStorageError] = React.useState<string | null>(null);
  const pushState = useAdminPushSubscription();
  const devicePermissions = useDevicePermissions();
  const online = useOnlineStatus();
  const installPrompt = useInstallPrompt();
  const back = useBackNavigation(adminPath('/mobile/profile'));
  const [installBannerDismissed, setInstallBannerDismissedState] = React.useState(() => getInstallBannerDismissed());
  const installBanner = shouldShowInstallBanner(
    {
      isInstalled: installPrompt.isInstalled,
      isStandalone: installPrompt.isStandalone,
      canInstall: installPrompt.canInstall,
      isIos: installPrompt.isIos,
    },
    installBannerDismissed,
  );

  const pushDescription = React.useMemo(() => {
    if (!pushState.supported) {
      return t('mobileSettings.pushUnsupported', 'Push wird auf diesem Gerät nicht unterstützt.');
    }
    if (pushState.permission === 'denied') {
      return t('mobileSettings.pushDenied', 'Benachrichtigungen sind im Browser blockiert.');
    }
    if (pushState.subscribed) {
      return t('mobileSettings.pushActive', 'Push aktiv');
    }
    return t('mobileSettings.pushInactive', 'Push deaktiviert');
  }, [pushState.permission, pushState.subscribed, pushState.supported, t]);

  const permissionTone = (status: PermissionStatus) => {
    if (status === 'granted') {
      return 'success';
    }
    if (status === 'denied' || status === 'prompt') {
      return 'warning';
    }
    return 'muted';
  };

  const storageTone = (status: StorageStatus) => {
    if (status === 'persisted') {
      return 'success';
    }
    if (status === 'available') {
      return 'warning';
    }
    return 'muted';
  };

  const permissionLabel = (status: PermissionStatus) =>
    t(`mobileSettings.deviceStatusValues.${status}`, status);
  const storageLabel = (status: StorageStatus) =>
    t(`mobileSettings.deviceStatusValues.${status}`, status);
  const connectionLabel = online
    ? t('mobileSettings.deviceStatusValues.online', 'Online')
    : t('mobileSettings.deviceStatusValues.offline', 'Offline');

  React.useEffect(() => {
    (async () => {
      setLoading(true);
      try {
        const result = await getNotificationPreferences();
        const defaultsMerged: NotificationPreferences = result.defaults ?? {};
        const prefs = { ...defaultsMerged, ...(result.preferences ?? {}) };
        AVAILABLE_PREFS.forEach((key) => {
          if (prefs[key] === undefined) {
            prefs[key] = defaultsMerged[key] ?? false;
          }
        });
        setPreferences(prefs);
        setDefaults(defaultsMerged);
        setError(null);
      } catch (err) {
        setError(getApiErrorMessage(err, t('settings.notifications.errorLoad', 'Benachrichtigungen konnten nicht geladen werden.')));
      } finally {
        setLoading(false);
      }
    })();
  }, [t]);

  React.useEffect(() => {
    if (devicePermissions.storage === 'persisted') {
      setStorageError(null);
    }
  }, [devicePermissions.storage]);

  const handleReplayTour = () => {
    setTourSeen(false);
    navigate(`${ADMIN_HOME_PATH}?tour=1`);
  };

  const handleResetInstallBanner = () => {
    setInstallBannerDismissed(false);
    setInstallBannerDismissedState(false);
  };

  const togglePref = (key: PreferenceKey) => {
    setPreferences((prev) => ({
      ...prev,
      [key]: !prev[key],
    }));
  };

  const handleSave = async () => {
    setSaving(true);
    try {
      const payload: NotificationPreferences = {};
      AVAILABLE_PREFS.forEach((key) => {
        payload[key] = Boolean(preferences[key]);
      });
      await updateNotificationPreferences(payload);
      setError(null);
    } catch (err) {
      setError(getApiErrorMessage(err, t('settings.notifications.errorSave', 'Speichern fehlgeschlagen')));
    } finally {
      setSaving(false);
    }
  };

  const handleReset = () => {
    setPreferences(defaults);
  };

  const handleStoragePersist = async () => {
    setStorageSaving(true);
    const granted = await devicePermissions.requestPersistentStorage();
    setStorageSaving(false);
    if (granted) {
      setStorageError(null);
      void devicePermissions.refresh();
    } else {
      setStorageError(
        t('mobileSettings.deviceStorageError', 'Offline-Schutz konnte nicht aktiviert werden.')
      );
    }
  };

  return (
    <MobileShell activeTab="profile" title={t('mobileSettings.title', 'Settings')} onBack={back}>
      {error ? (
        <MobileCard>
          <Text fontWeight="700" color={danger}>
            {error}
          </Text>
        </MobileCard>
      ) : null}
      <MobileInstallBanner
        state={installBanner}
        onInstall={installPrompt.canInstall ? () => void installPrompt.promptInstall() : undefined}
        onDismiss={() => {
          setInstallBannerDismissed(true);
          setInstallBannerDismissedState(true);
        }}
      />

      <MobileCard space="$3">
        <XStack alignItems="center" space="$2">
          <Shield size={18} color={text} />
          <Text fontSize="$md" fontWeight="800" color={text}>
            {t('mobileSettings.accountTitle', 'Account')}
          </Text>
        </XStack>
        <Text fontSize="$sm" color={muted}>
          {user?.name ?? user?.email ?? t('settings.session.unknown', 'Benutzer')}
        </Text>
        {user?.tenant_id ? (
          <PillBadge tone="muted">{t('mobileSettings.tenantBadge', 'Tenant #{{id}}', { id: user.tenant_id })}</PillBadge>
        ) : null}
        <XStack space="$2">
          <CTAButton label={t('settings.profile.actions.openProfile', 'Profil bearbeiten')} onPress={() => navigate(ADMIN_PROFILE_ACCOUNT_PATH)} />
          <CTAButton label={t('settings.session.logout', 'Abmelden')} tone="ghost" onPress={() => logout({ redirect: adminPath('/logout') })} />
        </XStack>
      </MobileCard>

      <MobileCard space="$3">
        <XStack alignItems="center" space="$2">
          <Bell size={18} color={text} />
          <Text fontSize="$md" fontWeight="800" color={text}>
            {t('mobileSettings.notificationsTitle', 'Notifications')}
          </Text>
        </XStack>
        {loading ? (
          <Text fontSize="$sm" color={muted}>
            {t('mobileSettings.notificationsLoading', 'Loading settings ...')}
          </Text>
        ) : (
          <YGroup {...({ borderRadius: "$4", borderWidth: 1, borderColor: border, overflow: "hidden" } as any)}>
            <YGroup.Item>
              <ListItem
                hoverTheme
                pressTheme
                paddingVertical="$2"
                paddingHorizontal="$3"
                title={
                  <Text fontSize="$sm" color={text} fontWeight="700">
                    {t('mobileSettings.pushTitle', 'App Push')}
                  </Text>
                }
                subTitle={
                  <Text fontSize="$xs" color={muted}>
                    {pushState.loading
                      ? t('mobileSettings.pushLoading', 'Lädt ...')
                      : pushDescription}
                  </Text>
                }
                iconAfter={
                  <Switch
                    size="$4"
                    checked={pushState.subscribed}
                    onCheckedChange={(value) => {
                      if (value) {
                        void pushState.enable();
                      } else {
                        void pushState.disable();
                      }
                    }}
                    disabled={!pushState.supported || pushState.permission === 'denied' || pushState.loading}
                    aria-label={t('mobileSettings.pushTitle', 'App Push')}
                  >
                    <Switch.Thumb />
                  </Switch>
                }
              />
            </YGroup.Item>
            {AVAILABLE_PREFS.map((key, index) => (
              <YGroup.Item key={key}>
                <ListItem
                  hoverTheme
                  pressTheme
                  paddingVertical="$2"
                  paddingHorizontal="$3"
                  title={
                    <Text fontSize="$sm" color={text} fontWeight="700">
                      {t(`settings.notifications.keys.${key}.label`, key)}
                    </Text>
                  }
                  subTitle={
                    <Text fontSize="$xs" color={muted}>
                      {t(`settings.notifications.keys.${key}.description`, '')}
                    </Text>
                  }
                  iconAfter={
                    <Switch
                      size="$4"
                      checked={Boolean(preferences[key])}
                      onCheckedChange={() => togglePref(key)}
                      aria-label={t(`settings.notifications.keys.${key}.label`, key)}
                    >
                      <Switch.Thumb />
                    </Switch>
                  }
                />
              </YGroup.Item>
            ))}
          </YGroup>
        )}
        {pushState.error ? (
          <Text fontSize="$xs" color={danger}>
            {pushState.error}
          </Text>
        ) : null}
        <XStack space="$2">
          <CTAButton label={saving ? t('common.processing', '...') : t('settings.notifications.actions.save', 'Speichern')} onPress={() => handleSave()} />
          <CTAButton label={t('common.reset', 'Reset')} tone="ghost" onPress={() => handleReset()} />
        </XStack>
      </MobileCard>

      <MobileCard space="$3">
        <XStack alignItems="center" space="$2">
          <Smartphone size={18} color={text} />
          <Text fontSize="$md" fontWeight="800" color={text}>
            {t('mobileSettings.deviceTitle', 'Device & permissions')}
          </Text>
        </XStack>
        <Text fontSize="$sm" color={muted}>
          {t('mobileSettings.deviceDescription', 'Check permissions so the admin app stays fast and offline-ready.')}
        </Text>
        {devicePermissions.loading ? (
          <Text fontSize="$sm" color={muted}>
            {t('mobileSettings.deviceLoading', 'Checking device status ...')}
          </Text>
        ) : (
          <YStack space="$2">
            <XStack alignItems="center" justifyContent="space-between" gap="$2">
              <YStack flex={1} space="$1">
                <Text fontSize="$sm" fontWeight="700" color={text}>
                  {t('mobileSettings.deviceStatus.notifications.label', 'Notifications')}
                </Text>
                <Text fontSize="$xs" color={muted}>
                  {t('mobileSettings.deviceStatus.notifications.description', 'Allow alerts and admin updates.')}
                </Text>
              </YStack>
              <PillBadge tone={permissionTone(devicePermissions.notifications)}>
                {permissionLabel(devicePermissions.notifications)}
              </PillBadge>
            </XStack>
            <XStack alignItems="center" justifyContent="space-between" gap="$2">
              <YStack flex={1} space="$1">
                <Text fontSize="$sm" fontWeight="700" color={text}>
                  {t('mobileSettings.deviceStatus.camera.label', 'Camera')}
                </Text>
                <Text fontSize="$xs" color={muted}>
                  {t('mobileSettings.deviceStatus.camera.description', 'Needed for QR scans and quick capture.')}
                </Text>
              </YStack>
              <PillBadge tone={permissionTone(devicePermissions.camera)}>
                {permissionLabel(devicePermissions.camera)}
              </PillBadge>
            </XStack>
            <XStack alignItems="center" justifyContent="space-between" gap="$2">
              <YStack flex={1} space="$1">
                <Text fontSize="$sm" fontWeight="700" color={text}>
                  {t('mobileSettings.deviceStatus.storage.label', 'Offline storage')}
                </Text>
                <Text fontSize="$xs" color={muted}>
                  {t('mobileSettings.deviceStatus.storage.description', 'Protect cached data from eviction.')}
                </Text>
              </YStack>
              <PillBadge tone={storageTone(devicePermissions.storage)}>
                {storageLabel(devicePermissions.storage)}
              </PillBadge>
            </XStack>
            <XStack alignItems="center" justifyContent="space-between" gap="$2">
              <YStack flex={1} space="$1">
                <Text fontSize="$sm" fontWeight="700" color={text}>
                  {t('mobileSettings.deviceStatus.connection.label', 'Connection')}
                </Text>
                <Text fontSize="$xs" color={muted}>
                  {t('mobileSettings.deviceStatus.connection.description', 'Shows if the app is online or offline.')}
                </Text>
              </YStack>
              <PillBadge tone={online ? 'success' : 'warning'}>{connectionLabel}</PillBadge>
            </XStack>
          </YStack>
        )}
        {devicePermissions.storage === 'available' ? (
          <CTAButton
            label={storageSaving ? t('common.processing', '...') : t('mobileSettings.deviceStorageAction', 'Enable offline protection')}
            onPress={() => handleStoragePersist()}
            disabled={storageSaving}
          />
        ) : null}
        {storageError ? (
          <Text fontSize="$xs" color={danger}>
            {storageError}
          </Text>
        ) : null}
      </MobileCard>

      <MobileCard space="$3">
        <XStack alignItems="center" space="$2">
          <Sparkles size={18} color={text} />
          <Text fontSize="$md" fontWeight="800" color={text}>
            {t('mobileSettings.experienceTitle', 'Experience')}
          </Text>
        </XStack>
        <Text fontSize="$sm" color={muted}>
          {t('mobileSettings.experienceBody', 'Replay the quick tour or re-enable the install banner.')}
        </Text>
        <XStack space="$2">
          <CTAButton
            label={t('mobileSettings.experienceReplay', 'Replay quick tour')}
            onPress={handleReplayTour}
            fullWidth={false}
          />
          <CTAButton
            label={t('mobileSettings.experienceResetInstall', 'Show install banner')}
            tone="ghost"
            onPress={handleResetInstallBanner}
            fullWidth={false}
            disabled={!installBannerDismissed}
          />
        </XStack>
      </MobileCard>

      <MobileCard space="$3">
        <XStack alignItems="center" space="$2">
          <User size={18} color={text} />
          <Text fontSize="$md" fontWeight="800" color={text}>
            {t('settings.appearance.title', 'Darstellung')}
          </Text>
        </XStack>
        <Text fontSize="$sm" color={muted}>
          {t('settings.appearance.description', 'Schalte Dark-Mode oder passe Branding im Admin an.')}
        </Text>
        <CTAButton label={t('settings.appearance.title', 'Darstellung & Branding')} tone="ghost" onPress={() => navigate(adminPath('/settings'))} />
      </MobileCard>
    </MobileShell>
  );
}
