import { useEffect, useMemo, useState } from 'react';
import { calculateExercise, calculateTotal } from '../utils/patCalculations';
import { supabase } from '../lib/supabaseClient';
import { normalizeExerciseValue } from '../utils/exerciseInputRules';
import {
  cloneAssessment,
  getFinalizeDisabledReason,
  isAssessmentComplete
} from '../utils/assessmentState';

const generateId = () => (typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Date.now().toString());

const mapFromDb = (row) => ({
  id: row.id,
  patType: row.pat_type,
  datum: row.datum,
  name: row.name,
  exercises: cloneAssessment(row.exercises || []),
  isFinalized: Boolean(row.is_finalized),
  finalizedAt: row.finalized_at || null,
  finalizationReminderSentAt: row.finalization_reminder_sent_at || null
});

const mapToDb = (assessment, userId) => ({
  id: assessment.id,
  user_id: userId,
  pat_type: assessment.patType,
  datum: assessment.datum,
  name: assessment.name,
  exercises: cloneAssessment(assessment.exercises),
  is_finalized: Boolean(assessment.isFinalized),
  finalized_at: assessment.finalizedAt || null,
  finalization_reminder_sent_at: assessment.finalizationReminderSentAt || null
});

export const useAssessments = (patTypes, user, options = {}) => {
  const { onAfterSave } = options;
  const [assessments, setAssessments] = useState([]);
  const [currentAssessment, setCurrentAssessment] = useState(null);
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);

  const canUseSupabase = useMemo(() => !!supabase && !!user?.id, [user]);

  useEffect(() => {
    if (!canUseSupabase) return;
    loadAssessments();
  }, [canUseSupabase]);

  const loadAssessments = async () => {
    if (!canUseSupabase) return;
    try {
      const { data, error } = await supabase
        .from('assessments')
        .select('*')
        .eq('user_id', user.id)
        .order('created_at', { ascending: false });

      if (error) throw error;

      setAssessments((data || []).map(mapFromDb));
    } catch (error) {
      console.error('Fehler beim Laden:', error);
      alert('Fehler beim Laden der Daten aus Supabase: ' + error.message);
    }
  };

  const createNewAssessment = (patType) => {
    const newAssessment = {
      id: generateId(),
      patType: patType,
      datum: new Date().toISOString().split('T')[0],
      name: '',
      exercises: cloneAssessment(patTypes[patType]),
      isFinalized: false,
      finalizedAt: null,
      finalizationReminderSentAt: null
    };
    setCurrentAssessment(newAssessment);
    setHasUnsavedChanges(false);
  };

  const openAssessment = (assessment) => {
    setCurrentAssessment(cloneAssessment(assessment));
    setHasUnsavedChanges(false);
  };

  const persistAssessment = async ({ finalize = false } = {}) => {
    if (!currentAssessment?.name || !currentAssessment?.datum) {
      alert('Bitte Name und Datum ausfüllen');
      return { ok: false };
    }

    if (currentAssessment?.isFinalized && !finalize) {
      alert('Final abgeschlossene Bewertungen können nicht mehr geändert werden.');
      return { ok: false };
    }

    if (finalize) {
      const finalizeDisabledReason = getFinalizeDisabledReason(currentAssessment);
      if (finalizeDisabledReason || !isAssessmentComplete(currentAssessment)) {
        alert(finalizeDisabledReason || 'Bitte alle Felder ausfüllen, bevor du final abschließt.');
        return { ok: false };
      }
    }

    if (!canUseSupabase) {
      alert('Supabase ist nicht konfiguriert. Bitte .env prüfen.');
      return { ok: false };
    }

    const exists = assessments.find((a) => a.id === currentAssessment.id);

    try {
      const nextAssessment = cloneAssessment(currentAssessment);
      nextAssessment.name = nextAssessment.name.trim();

      if (finalize) {
        nextAssessment.isFinalized = true;
        nextAssessment.finalizedAt = new Date().toISOString();
        nextAssessment.finalizationReminderSentAt = null;
      }

      const payload = mapToDb(nextAssessment, user.id);
      let saved = null;
      let nextAssessments = [];

      if (!exists) {
        const { data, error } = await supabase
          .from('assessments')
          .insert(payload)
          .select()
          .single();

        if (error) throw error;

        saved = mapFromDb(data);
        nextAssessments = [saved, ...assessments.filter((item) => item.id !== saved.id)];
        setAssessments(nextAssessments);
        setCurrentAssessment(saved);
      } else {
        const { data, error } = await supabase
          .from('assessments')
          .update(payload)
          .eq('id', currentAssessment.id)
          .eq('user_id', user.id)
          .select()
          .single();

        if (error) throw error;

        saved = mapFromDb(data);
        nextAssessments = assessments.map((item) => (item.id === saved.id ? saved : item));
        setAssessments(nextAssessments);
        setCurrentAssessment(saved);
      }

      if (typeof onAfterSave === 'function') {
        try {
          await onAfterSave({
            savedAssessment: saved,
            assessments: nextAssessments
          });
        } catch (postSaveError) {
          console.warn('Post-save hook failed:', postSaveError);
        }
      }

      setHasUnsavedChanges(false);
      return {
        ok: true,
        assessment: saved,
        assessments: nextAssessments
      };
    } catch (error) {
      alert('Fehler beim Speichern in Supabase: ' + error.message);
      return {
        ok: false,
        error
      };
    }
  };

  const handleSave = async () => persistAssessment();

  const finalizeAssessment = async () => persistAssessment({ finalize: true });

  const updateExerciseValue = (exerciseIndex, valueIndex, newValue, subType = null) => {
    if (!currentAssessment || currentAssessment.isFinalized) return;

    const updated = cloneAssessment(currentAssessment);
    const normalizedValue = normalizeExerciseValue(updated.exercises[exerciseIndex], newValue, subType);

    if (subType === 'a') {
      updated.exercises[exerciseIndex].subA[valueIndex] = normalizedValue;
    } else if (subType === 'b') {
      updated.exercises[exerciseIndex].subB[valueIndex] = normalizedValue;
    } else {
      updated.exercises[exerciseIndex].values[valueIndex] = normalizedValue;
    }

    const { durchschnitt, points } = calculateExercise(updated.exercises[exerciseIndex]);
    updated.exercises[exerciseIndex].durchschnitt = durchschnitt;
    updated.exercises[exerciseIndex].points = points;

    setCurrentAssessment(updated);
    setHasUnsavedChanges(true);
  };
  const deleteAssessment = async (id) => {
    if (!confirm('Möchten Sie diese Bewertung wirklich löschen?')) return;
    if (!canUseSupabase) {
      alert('Supabase ist nicht konfiguriert. Bitte .env prüfen.');
      return;
    }

    const { error } = await supabase.from('assessments').delete().eq('id', id).eq('user_id', user.id);
    if (error) {
      alert('Fehler beim Löschen: ' + error.message);
      return;
    }

    setAssessments((prev) => prev.filter((a) => a.id !== id));
  };

  return {
    assessments,
    currentAssessment,
    setCurrentAssessment,
    hasUnsavedChanges,
    setHasUnsavedChanges,
    createNewAssessment,
    openAssessment,
    handleSave,
    finalizeAssessment,
    deleteAssessment,
    updateExerciseValue,
    calculateTotal: () => calculateTotal(currentAssessment?.exercises || [])
  };
};
