import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  IonButton,
  IonButtons,
  IonContent,
  IonHeader,
  IonIcon,
  IonPage,
  IonRefresher,
  IonRefresherContent,
  IonSkeletonText,
  IonToolbar,
  useIonViewWillEnter,
} from '@ionic/react';
import {
  addOutline,
  analyticsOutline,
  checkmarkCircle,
  personCircleOutline,
  sparklesOutline,
} from 'ionicons/icons';
import { Redirect, useHistory } from 'react-router-dom';
import type { Tables } from '../database.types';
import { supabase } from '../supabase';
import EmptyState from '../components/EmptyState';
import HabitCard from '../components/HabitCard';
import HabitFormModal from '../components/HabitFormModal';
import {
  Style,
  setStatusBarBackground,
  setStatusBarStyle,
} from '../utils/statusBar';

interface HabitWithMeta extends Tables<'habits'> {
  completions: Tables<'habit_completions'>[];
}

const formatDate = (date: Date) => date.toISOString().slice(0, 10);

const calculateCurrentStreak = (dates: string[]) => {
  const unique = Array.from(new Set(dates)).sort((a, b) => b.localeCompare(a));
  let streak = 0;
  let cursor = new Date();

  if (!unique.includes(formatDate(cursor))) {
    cursor.setDate(cursor.getDate() - 1);
  }

  while (unique.includes(formatDate(cursor))) {
    streak += 1;
    cursor.setDate(cursor.getDate() - 1);
  }

  return streak;
};

const Home: React.FC = () => {
  const history = useHistory();
  const [sessionChecked, setSessionChecked] = useState(false);
  const [userId, setUserId] = useState<string | null>(null);
  const [habits, setHabits] = useState<HabitWithMeta[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [showCreateModal, setShowCreateModal] = useState(false);
  const [busyHabitId, setBusyHabitId] = useState<string | null>(null);

  useIonViewWillEnter(() => {
    setStatusBarStyle(Style.Dark);
    setStatusBarBackground('#ffffff');
  });

  const loadDashboard = useCallback(async () => {
    setError('');

    const {
      data: { session },
      error: sessionError,
    } = await supabase.auth.getSession();

    if (sessionError) {
      setError(sessionError.message);
      setSessionChecked(true);
      setLoading(false);
      return;
    }

    if (!session?.user) {
      setUserId(null);
      setSessionChecked(true);
      setLoading(false);
      return;
    }

    setUserId(session.user.id);
    setSessionChecked(true);

    const { data, error: habitsError } = await supabase
      .from('habits')
      .select('*, completions:habit_completions(*)')
      .order('created_at', { ascending: true });

    if (habitsError) {
      setError(habitsError.message);
      setLoading(false);
      return;
    }

    setHabits((data ?? []) as HabitWithMeta[]);
    setLoading(false);
  }, []);

  useEffect(() => {
    loadDashboard();
  }, [loadDashboard]);

  const today = formatDate(new Date());

  const habitStats = useMemo(() => {
    const last7Days = Array.from({ length: 7 }, (_, index) => {
      const date = new Date();
      date.setDate(date.getDate() - index);
      return formatDate(date);
    });

    return habits.reduce<
      Record<string, { streak: number; weekRate: number; doneToday: boolean }>
    >((acc, habit) => {
      const completionDates = habit.completions.map(
        (entry) => entry.completed_on
      );
      const completedInWeek = completionDates.filter((date) =>
        last7Days.includes(date)
      ).length;

      acc[habit.id] = {
        streak: calculateCurrentStreak(completionDates),
        weekRate: Math.round((completedInWeek / last7Days.length) * 100),
        doneToday: completionDates.includes(today),
      };

      return acc;
    }, {});
  }, [habits, today]);

  const totalCompletedToday = habits.filter(
    (habit) => habitStats[habit.id]?.doneToday
  ).length;
  const longestStreak = habits.reduce(
    (max, habit) => Math.max(max, habitStats[habit.id]?.streak ?? 0),
    0
  );
  const completionRatio = habits.length
    ? totalCompletedToday / habits.length
    : 0;
  const pendingCount = Math.max(habits.length - totalCompletedToday, 0);

  const createHabit = async (values: {
    name: string;
    targetDescription: string;
    color: string;
  }) => {
    if (!userId) throw new Error('You need to be logged in.');

    const { error: insertError } = await supabase.from('habits').insert({
      user_id: userId,
      name: values.name,
      target_description: values.targetDescription || null,
      color: values.color,
    });

    if (insertError) throw insertError;
    await loadDashboard();
  };

  const toggleHabit = async (habit: HabitWithMeta) => {
    if (!userId) return;
    setBusyHabitId(habit.id);

    const existing = habit.completions.find(
      (entry) => entry.completed_on === today
    );

    if (existing) {
      const { error: deleteError } = await supabase
        .from('habit_completions')
        .delete()
        .eq('id', existing.id);
      if (deleteError) setError(deleteError.message);
    } else {
      const { error: insertError } = await supabase
        .from('habit_completions')
        .insert({
          habit_id: habit.id,
          user_id: userId,
          completed_on: today,
        });
      if (insertError) setError(insertError.message);
    }

    await loadDashboard();
    setBusyHabitId(null);
  };

  const deleteHabit = async (habitId: string) => {
    setBusyHabitId(habitId);
    const { error: deleteError } = await supabase
      .from('habits')
      .delete()
      .eq('id', habitId);
    if (deleteError) {
      setError(deleteError.message);
    }
    await loadDashboard();
    setBusyHabitId(null);
  };

  if (sessionChecked && !userId) {
    return <Redirect to="/auth" />;
  }

  return (
    <IonPage>
      <IonHeader className="ion-no-border home-header">
        <IonToolbar>
          <IonButtons slot="end">
            <IonButton
              className="soft-icon-button"
              onClick={() => history.push('/stats')}
            >
              <IonIcon icon={analyticsOutline} />
            </IonButton>
            <IonButton
              className="soft-icon-button"
              onClick={() => history.push('/account')}
            >
              <IonIcon icon={personCircleOutline} />
            </IonButton>
          </IonButtons>
        </IonToolbar>
      </IonHeader>

      <IonContent fullscreen className="home-content">
        <IonRefresher
          slot="fixed"
          onIonRefresh={async (e) => {
            await loadDashboard();
            e.detail.complete();
          }}
        >
          <IonRefresherContent />
        </IonRefresher>

        <div className="dashboard-shell home-shell ion-padding">
          <section className="habits-hero">
            <div className="habits-hero-top">
              <div>
                <p className="hero-kicker">Habits ({habits.length})</p>
                <div className="hero-title-wrap">
                  <h1>Daily</h1>
                  <span>Weekly</span>
                </div>
              </div>
              <IonButton
                className="hero-add-button"
                fill="clear"
                onClick={() => setShowCreateModal(true)}
              >
                <IonIcon icon={addOutline} />
              </IonButton>
            </div>

            <div className="hero-progress-track" aria-hidden="true">
              <div
                className="hero-progress-fill"
                style={{ width: `${Math.max(completionRatio * 100, 6)}%` }}
              >
                <span className="hero-progress-dot" />
              </div>
            </div>

            <div className="hero-progress-meta">
              <span>{totalCompletedToday} completed today</span>
              <span>{Math.round(completionRatio * 100)}% completed</span>
            </div>
          </section>

          {loading ? (
            <div className="home-routine-panel">
              <div className="stack-list home-habit-stack">
                <IonSkeletonText
                  animated
                  style={{
                    width: '100%',
                    height: '82px',
                    borderRadius: '24px',
                  }}
                />
                <IonSkeletonText
                  animated
                  style={{
                    width: '100%',
                    height: '82px',
                    borderRadius: '24px',
                  }}
                />
                <IonSkeletonText
                  animated
                  style={{
                    width: '100%',
                    height: '82px',
                    borderRadius: '24px',
                  }}
                />
                <IonSkeletonText
                  animated
                  style={{
                    width: '100%',
                    height: '82px',
                    borderRadius: '24px',
                  }}
                />
              </div>
            </div>
          ) : error ? (
            <div className="inline-message error-card home-inline-card">
              <h3>Couldn&apos;t load your habits</h3>
              <p>{error}</p>
              <IonButton onClick={loadDashboard}>Try Again</IonButton>
            </div>
          ) : habits.length === 0 ? (
            <div className="home-routine-panel">
              <EmptyState
                title="Start your first routine"
                message="Create one small daily habit and begin building your streak story today."
                actionLabel="Create First Habit"
                onAction={() => setShowCreateModal(true)}
              />
            </div>
          ) : (
            <>
              <section className="home-routine-panel">
                <div className="stack-list home-habit-stack">
                  {habits.map((habit) => (
                    <HabitCard
                      key={habit.id}
                      habit={habit}
                      completedToday={habitStats[habit.id]?.doneToday ?? false}
                      currentStreak={habitStats[habit.id]?.streak ?? 0}
                      completionRate={habitStats[habit.id]?.weekRate ?? 0}
                      onToggle={() => toggleHabit(habit)}
                      onDelete={() => deleteHabit(habit.id)}
                      busy={busyHabitId === habit.id}
                    />
                  ))}
                </div>
              </section>

              <section className="home-complete-section">
                <p className="home-section-label">Momentum</p>
                <div className="home-summary-card">
                  <div
                    className="summary-ring"
                    style={{
                      background: `conic-gradient(#7c3aed 0deg, #a855f7 ${completionRatio * 360}deg, rgba(109, 40, 217, 0.08) ${completionRatio * 360}deg 360deg)`,
                    }}
                  >
                    <div className="summary-ring-inner">
                      {Math.round(completionRatio * 100)}%
                    </div>
                  </div>
                  <div className="summary-copy">
                    <h3>Keep your rhythm</h3>
                    <p>
                      {pendingCount === 0
                        ? 'Everything is complete today. Enjoy the streak.'
                        : `${pendingCount} habit${pendingCount === 1 ? '' : 's'} left to protect today's routine.`}
                    </p>
                    <div className="summary-metrics">
                      <span>
                        <IonIcon icon={sparklesOutline} /> {totalCompletedToday}{' '}
                        done
                      </span>
                      <span>
                        <IonIcon icon={checkmarkCircle} /> {longestStreak} day
                        best streak
                      </span>
                    </div>
                  </div>
                </div>
              </section>
            </>
          )}
        </div>

        <HabitFormModal
          isOpen={showCreateModal}
          onDismiss={() => setShowCreateModal(false)}
          onSubmit={createHabit}
        />
      </IonContent>
    </IonPage>
  );
};

export default Home;
