import { useRef, useState, useEffect } from 'react';
import { View, ScrollView, Text, Alert, Switch, findNodeHandle, UIManager } from 'react-native';
import { useTranslation } from 'react-i18next';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useRouter } from 'expo-router';
import { AppHeader } from '../../components/AppHeader';
import { ProfileHeader, type AuthProvider } from '../../components/profile/ProfileHeader';
import { StatsBar } from '../../components/profile/StatsBar';
import { ApprovedDomainsList } from '../../components/profile/ApprovedDomainsList';
import { StreakSection, type CooldownEntry } from '../../components/profile/StreakSection';
import { UrgeStatsCard, type HelpedByEntry } from '../../components/profile/UrgeStatsCard';
import { DemographicsAccordion, type Demographics } from '../../components/profile/DemographicsAccordion';
import { DigaMissionBanner } from '../../components/profile/DigaMissionBanner';
import { useColors } from '../../lib/theme';
import type { Plan } from '../../hooks/useUserPlan';
import { useMe } from '../../hooks/useMe';
import { useAuthStore } from '../../stores/auth';
import {
  useSocialStats,
  useApprovedDomains,
  useCooldownHistory,
  useCooldownHistoryFull,
  useSosInsights,
  useDemographics,
} from '../../hooks/useProfileData';
import { apiFetch } from '../../lib/api';
import { untrackSelf, retrackSelf } from '../../hooks/useOnlineUsers';

const EMPTY_COOLDOWNS: CooldownEntry[] = [];

function isDemographicsComplete(d: Demographics): boolean {
  const base =
    d.birthYear !== null &&
    !!d.gender &&
    !!d.maritalStatus &&
    !!d.employmentStatus &&
    !!d.bundesland &&
    !!d.city;
  if (!base) return false;
  const status = d.employmentStatus!;
  const needsShift = ['employed', 'self_employed'].includes(status);
  const needsIndustry = ['employed', 'self_employed', 'in_training'].includes(status);
  const needsTenure = ['employed', 'self_employed'].includes(status);
  if (needsShift && d.shiftWork === null) return false;
  if (needsIndustry && !d.industry) return false;
  if (needsTenure && !d.jobTenure) return false;
  return true;
}

const EMPTY_DEMOGRAPHICS: Demographics = {
  birthYear: null,
  gender: null,
  maritalStatus: null,
  employmentStatus: null,
  shiftWork: null,
  industry: null,
  jobTenure: null,
  bundesland: null,
  city: null,
};

function formatMemberSince(isoString: string | undefined): string {
  if (!isoString) return '';
  const d = new Date(isoString);
  return d.toLocaleDateString('de-DE', { month: 'long', year: 'numeric' });
}

function formatStreakStartDate(isoString: string | undefined): string {
  if (!isoString) return '';
  const d = new Date(isoString);
  return d.toLocaleDateString('de-DE', { day: 'numeric', month: 'long', year: 'numeric' });
}

function mapHelpedBy(helpedBy: {
  breathing: number;
  game: number;
  talk: number;
  other: number;
}): HelpedByEntry[] {
  const entries: HelpedByEntry[] = [
    { key: 'breathing', label: 'Atemübung', count: helpedBy.breathing },
    { key: 'game', label: 'Spiel', count: helpedBy.game },
    { key: 'talk', label: 'Reden mit Lyra', count: helpedBy.talk },
    { key: 'other', label: 'Sonstiges', count: helpedBy.other },
  ];
  return entries.filter((e) => e.count > 0);
}

export default function ProfileScreen() {
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const colors = useColors();
  const { t } = useTranslation();
  const [bannerDismissed, setBannerDismissed] = useState(false);
  const [demographicsExpanded, setDemographicsExpanded] = useState(false);
  const { me } = useMe();
  const { user } = useAuthStore();

  const [presenceVisible, setPresenceVisible] = useState<boolean>(true);

  useEffect(() => {
    if (me?.presenceVisible !== undefined) {
      setPresenceVisible(me.presenceVisible);
    }
  }, [me?.presenceVisible]);

  async function togglePresence() {
    const next = !presenceVisible;
    setPresenceVisible(next);
    if (!next) {
      untrackSelf();
    } else if (user?.id) {
      retrackSelf(user.id);
    }
    try {
      await apiFetch('/api/me/presence-visibility', { method: 'POST', body: { visible: next } });
    } catch {
      setPresenceVisible(!next);
      if (next) {
        untrackSelf();
      } else if (user?.id) {
        retrackSelf(user.id);
      }
    }
  }

  const { stats: socialStats } = useSocialStats(me?.id);
  const { domains: approvedDomainsData } = useApprovedDomains();
  const { cooldownHistory } = useCooldownHistory();
  const { rawCooldowns } = useCooldownHistoryFull();
  const { sosInsights } = useSosInsights();
  const {
    demographics: serverDemographics,
    withdrawnAt,
    reload: reloadDemographics,
  } = useDemographics();

  const demographics: Demographics = serverDemographics ?? EMPTY_DEMOGRAPHICS;

  const scrollViewRef = useRef<ScrollView | null>(null);
  const demographicsAnchorRef = useRef<View | null>(null);

  const provider: AuthProvider =
    ((user?.app_metadata as { provider?: string } | undefined)?.provider as AuthProvider) ?? 'email';

  const profile = {
    nickname: me?.nickname ?? user?.email?.split('@')[0] ?? 'User',
    email: user?.email ?? '',
    avatar: me?.avatar ?? null,
    plan: ((me as { plan?: string } | null | undefined)?.plan ?? 'free') as Plan,
    memberSince: formatMemberSince(me?.created_at),
    provider,
  };

  const currentStreak = me?.streak ?? 0;
  // TODO(backend): longestDays + streakStartDate fehlen in /api/auth/me.
  // Backend-Agent: Profile-Tabelle braucht longestStreak:Int + streakStartedAt:DateTime.
  // Tracking: streakStartedAt wird bei jedem Streak-Reset auf NOW() gesetzt.
  const longestDays = currentStreak;
  const streakStartDate = formatStreakStartDate(me?.created_at);

  const showDigaBanner = currentStreak >= 30 && !bannerDismissed;
  const demoComplete = !withdrawnAt && isDemographicsComplete(demographics);

  function scrollToDemographics() {
    const node = demographicsAnchorRef.current;
    const scroll = scrollViewRef.current;
    if (!node || !scroll) return;
    const handle = findNodeHandle(node);
    const scrollHandle = findNodeHandle(scroll);
    if (!handle || !scrollHandle) return;
    UIManager.measureLayout(
      handle,
      scrollHandle,
      () => {},
      (_x, y) => {
        scroll.scrollTo({ y: Math.max(0, y - 16), animated: true });
      },
    );
  }

  function openDemographics() {
    setDemographicsExpanded(true);
    scrollToDemographics();
  }

  return (
    <View style={{ flex: 1, backgroundColor: colors.groupedBg }}>
      <AppHeader showBack title="Profil" />
      <ScrollView
        ref={scrollViewRef}
        style={{ flex: 1 }}
        contentContainerStyle={{ paddingBottom: insets.bottom + 80 }}
        showsVerticalScrollIndicator={false}
      >
        <ProfileHeader
          nickname={profile.nickname}
          email={profile.email}
          avatar={profile.avatar}
          plan={profile.plan}
          memberSince={profile.memberSince}
          provider={profile.provider}
          demographicsComplete={demoComplete}
          showDemographicsHint={!demoComplete}
          onDemographicsHintPress={openDemographics}
          onEditAvatar={() => router.push('/profile/edit')}
          onEditNickname={() => router.push('/profile/edit')}
        />

        <View
          style={{
            height: 1,
            backgroundColor: colors.border,
            marginHorizontal: 16,
          }}
        />

        <View style={{ marginTop: 16 }}>
          <StatsBar
            postsCount={socialStats?.postsCount ?? 0}
            followersCount={socialStats?.followersCount ?? 0}
            approvedDomainsCount={approvedDomainsData?.count ?? 0}
            onPostsPress={() => {}}
            onFollowersPress={() => {}}
            onApprovedDomainsPress={() => {}}
          />
        </View>

        {showDigaBanner ? (
          <DigaMissionBanner
            onDismiss={() => {
              setBannerDismissed(true);
              apiFetch('/api/profile/me/diga-banner-dismiss', { method: 'POST' }).catch(() => {});
            }}
            onContribute={() => {
              setBannerDismissed(true);
              scrollToDemographics();
            }}
          />
        ) : null}

        <StreakSection
          currentDays={currentStreak}
          longestDays={longestDays}
          startDate={streakStartDate}
          cooldowns={cooldownHistory?.items ?? EMPTY_COOLDOWNS}
          rawCooldowns={rawCooldowns}
        />

        <UrgeStatsCard
          sessions={sosInsights?.last30Days.sessions ?? 0}
          overcome={sosInsights?.last30Days.overcome ?? 0}
          helpedBy={
            sosInsights
              ? mapHelpedBy(sosInsights.helpedBy)
              : []
          }
          topEmotion={sosInsights?.topEmotion ?? null}
        />

        <View ref={demographicsAnchorRef} collapsable={false}>
          <DemographicsAccordion
            demographics={demographics}
            plan={profile.plan}
            expanded={demographicsExpanded}
            onChange={async (next) => {
              try {
                const result = await apiFetch<{ trialAwarded: boolean; expiresAt: string | null }>(
                  '/api/profile/me/demographics',
                  { method: 'PATCH', body: next },
                );
                reloadDemographics();
                if (result.trialAwarded) {
                  Alert.alert(
                    'Pro-Woche freigeschaltet',
                    'Danke fur deine DiGA-Daten. Du hast 7 Tage Pro kostenlos erhalten.',
                  );
                }
              } catch {
                // write failed — optimistic update not applied, server state preserved
              }
            }}
            onRevokeConsent={() => {
              Alert.alert(
                'Daten zuruckziehen',
                'Alle demografischen Angaben werden geloscht. Fortfahren?',
                [
                  { text: 'Abbrechen', style: 'cancel' },
                  {
                    text: 'Loschen',
                    style: 'destructive',
                    onPress: () => {
                      apiFetch('/api/profile/me/demographics', { method: 'DELETE' })
                        .then(() => reloadDemographics())
                        .catch(() => {});
                    },
                  },
                ],
              );
            }}
          />
        </View>

        <ApprovedDomainsList domains={approvedDomainsData?.list ?? []} />

        <View style={{ paddingHorizontal: 16, paddingTop: 24, gap: 8 }}>
          <Text
            style={{
              fontSize: 11,
              color: colors.textMuted,
              fontFamily: 'Nunito_700Bold',
              letterSpacing: 0.8,
            }}
          >
            {t('profile.privacy_section_title').toUpperCase()}
          </Text>
          <View
            style={{
              flexDirection: 'row',
              alignItems: 'center',
              justifyContent: 'space-between',
              backgroundColor: colors.card,
              padding: 14,
              borderRadius: 12,
              borderWidth: 1,
              borderColor: colors.border,
            }}
          >
            <View style={{ flex: 1, gap: 2 }}>
              <Text style={{ fontSize: 14, color: colors.text, fontFamily: 'Nunito_600SemiBold' }}>
                {t('profile.show_online_status')}
              </Text>
              <Text style={{ fontSize: 12, color: colors.textMuted, fontFamily: 'Nunito_400Regular' }}>
                {t('profile.show_online_status_hint')}
              </Text>
            </View>
            <Switch value={presenceVisible} onValueChange={togglePresence} />
          </View>
        </View>

        <View style={{ height: 24 }} />
      </ScrollView>
    </View>
  );
}
