import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from '../i18n/LanguageContext';
import PatList from './PatList/PatList';
import PatDetail from './PatDetail/PatDetail';
import AnalysisTab from './Analysis/AnalysisTab';
import { patTypes } from '../data/patTypes';
import { useAssessments } from '../hooks/useAssessments';
import { getAchievement, getPatTypeColor } from '../utils/patCalculations';
import LiveOverview from './LiveOverview';
import { buildAnalysis } from '../utils/analysisEngine';
import { generateTrainingPlan } from '../utils/trainingPlanGenerator';
import { saveTrainingPlanWithSessions } from '../lib/trainingPlanService';
import {
  createAssessmentShareLink,
  listAssessmentShares,
  revokeAssessmentShare
} from '../lib/assessmentShareService';
import { getFinalizeDisabledReason } from '../utils/assessmentState';

const copyToClipboard = async (value) => {
  if (typeof navigator === 'undefined' || !navigator.clipboard?.writeText) return false;
  await navigator.clipboard.writeText(value);
  return true;
};
const isLocalhostShare = () =>
  typeof window !== 'undefined' &&
  ['localhost', '127.0.0.1'].includes(window.location.hostname);

export default function PatTestManager({
  user,
  activeTab = 'assessments',
  onEditingStateChange,
  testsVisible = false,
  isProfileLoading = false
}) {
  const t = useTranslation();
  const visiblePatTypes = useMemo(() => patTypes || {}, []);
  const patTypeOptions = Object.keys(visiblePatTypes);
  const [showList, setShowList] = useState(true);
  const [selectedPatType, setSelectedPatType] = useState(() => patTypeOptions[0] || '');
  const [showSaveDialog, setShowSaveDialog] = useState(false);
  const [assessmentShareTokens, setAssessmentShareTokens] = useState({});

  useEffect(() => {
    onEditingStateChange?.(!showList);
  }, [onEditingStateChange, showList]);

  useEffect(() => {
    if (!patTypeOptions.length) return;
    if (!selectedPatType || !patTypeOptions.includes(selectedPatType)) {
      setSelectedPatType(patTypeOptions[0]);
    }
  }, [patTypeOptions, selectedPatType]);

  const regenerateTrainingPlan = useCallback(async ({ savedAssessment, assessments: nextAssessments }) => {
    if (!savedAssessment?.patType || !nextAssessments?.length) return;

    const analysis = buildAnalysis(nextAssessments, savedAssessment.patType, {
      windowSize: 5,
      missingStrategy: 'zero'
    });

    if (!analysis.windowedAssessments.length) return;

    const generated = generateTrainingPlan({
      topWeaknesses: analysis.topWeaknesses,
      topStrengths: analysis.topStrengths,
      durationWeeks: 4,
      sessionsPerWeek: 3,
      sessionMix: '1-main-2-secondary'
    });

    const result = await saveTrainingPlanWithSessions({
      patType: savedAssessment.patType,
      analysisSnapshot: analysis,
      durationWeeks: 4,
      sessionsPerWeek: 3,
      sessions: generated.sessions
    });

    if (!result.ok) {
      console.warn('Automatische Plan-Neugenerierung fehlgeschlagen:', result.error?.message || result.error);
    }
  }, []);

  const {
    assessments,
    currentAssessment,
    setCurrentAssessment,
    hasUnsavedChanges,
    setHasUnsavedChanges,
    createNewAssessment,
    openAssessment,
    handleSave,
    finalizeAssessment,
    deleteAssessment,
    updateExerciseValue,
    calculateTotal
  } = useAssessments(visiblePatTypes, user, {
    onAfterSave: regenerateTrainingPlan
  });
  const visibleAssessments = assessments;
  const visibleAssessmentIds = useMemo(
    () => visibleAssessments.map((assessment) => assessment.id),
    [visibleAssessments]
  );
  const isCurrentAssessmentPersisted = useMemo(
    () => assessments.some((assessment) => assessment.id === currentAssessment?.id),
    [assessments, currentAssessment?.id]
  );
  const isCurrentAssessmentShareActive = Boolean(
    currentAssessment?.id && assessmentShareTokens[currentAssessment.id]
  );
  const isCurrentAssessmentReadOnly = Boolean(currentAssessment?.isFinalized);

  useEffect(() => {
    let ignore = false;

    const loadAssessmentShares = async () => {
      if (!user?.id || !visibleAssessmentIds.length) {
        setAssessmentShareTokens({});
        return;
      }

      try {
        const shareTokens = await listAssessmentShares(visibleAssessmentIds);
        if (!ignore) {
          setAssessmentShareTokens(shareTokens);
        }
      } catch (error) {
        console.warn('Freigaben konnten nicht geladen werden:', error);
        if (!ignore) {
          setAssessmentShareTokens({});
        }
      }
    };

    loadAssessmentShares();

    return () => {
      ignore = true;
    };
  }, [user?.id, visibleAssessmentIds]);

  const handleBackToList = () => {
    if (hasUnsavedChanges && !isCurrentAssessmentReadOnly) {
      setShowSaveDialog(true);
    } else {
      setShowList(true);
    }
  };

  const executeSave = async () => {
    const result = await handleSave();
    if (result?.ok) {
      alert(t('patmgr.saved'));
    }
    return result;
  };

  const handleFinalize = useCallback(async () => {
    const result = await finalizeAssessment();
    if (result?.ok) {
      alert(t('patmgr.finalized'));
    }
  }, [finalizeAssessment]);

  const handleSaveAndExit = async () => {
    if (!currentAssessment?.name || !currentAssessment?.datum) {
      alert(t('patmgr.fill_name_date'));
      return;
    }

    const result = await executeSave();
    if (result?.ok) {
      setShowSaveDialog(false);
      setShowList(true);
    }
  };

  const handleDiscardAndExit = () => {
    setShowSaveDialog(false);
    setHasUnsavedChanges(false);
    setShowList(true);
  };

  const handleCancelExit = () => {
    setShowSaveDialog(false);
  };
  const handleShare = useCallback(async (assessment) => {
    try {
      const { token, url } = await createAssessmentShareLink(assessment);
      const label = assessment?.name || assessment?.patType || 'dieser Test';
      const localhostHint = isLocalhostShare()
        ? `\n\n${t('patmgr.share_localhost_hint')}`
        : '';
      setAssessmentShareTokens((prev) => ({
        ...prev,
        [assessment.id]: token
      }));

      try {
        const copied = await copyToClipboard(url);
        if (copied) {
          alert(`${t('patmgr.share_copied', { label })}${localhostHint}`);
          return;
        }
      } catch (clipboardError) {
        console.warn('Kopieren in die Zwischenablage fehlgeschlagen:', clipboardError);
      }

      window.prompt(`${t('patmgr.share_link_label', { label })}${localhostHint}`, url);
    } catch (error) {
      alert(t('patmgr.share_error', { error: error.message || error }));
    }
  }, []);
  const handleRevokeShare = useCallback(async (assessment) => {
    const label = assessment?.name || assessment?.patType || 'dieser Test';

    try {
      await revokeAssessmentShare(assessment.id);
      setAssessmentShareTokens((prev) => {
        const next = { ...prev };
        delete next[assessment.id];
        return next;
      });
      alert(t('patmgr.unshare_success', { label }));
    } catch (error) {
      alert(t('patmgr.unshare_error', { error: error.message || error }));
    }
  }, []);
  const handleShareFromDetail = useCallback(() => {
    if (!currentAssessment) return;

    if (isProfileLoading) {
      alert(t('patmgr.profile_loading'));
      return;
    }

    if (!testsVisible) {
      alert(t('patmgr.enable_visible'));
      return;
    }

    if (!isCurrentAssessmentPersisted) {
      alert(t('patmgr.save_before_share'));
      return;
    }

    if (hasUnsavedChanges) {
      alert(t('patmgr.save_for_share'));
      return;
    }

    handleShare(currentAssessment);
  }, [
    currentAssessment,
    handleShare,
    hasUnsavedChanges,
    isCurrentAssessmentPersisted,
    isProfileLoading,
    testsVisible
  ]);
  const handleRevokeShareFromDetail = useCallback(() => {
    if (!currentAssessment || !isCurrentAssessmentShareActive) return;
    handleRevokeShare(currentAssessment);
  }, [currentAssessment, handleRevokeShare, isCurrentAssessmentShareActive]);
  const shareDisabledReason = !isCurrentAssessmentPersisted
    ? t('patmgr.save_first')
    : hasUnsavedChanges
      ? t('patmgr.save_for_share')
      : isProfileLoading
        ? t('patmgr.profile_loading_btn')
        : !testsVisible
          ? t('patmgr.enable_visible_btn')
          : '';
  const finalizeDisabledReason = getFinalizeDisabledReason(currentAssessment);

  if (!showList) {
    return (
      <PatDetail
        currentAssessment={currentAssessment}
        hasUnsavedChanges={hasUnsavedChanges}
        onBack={handleBackToList}
        onSave={executeSave}
        onAssessmentChange={setCurrentAssessment}
        onUpdateExercise={updateExerciseValue}
        onMarkDirty={() => setHasUnsavedChanges(true)}
        showSaveDialog={showSaveDialog}
        onSaveAndExit={handleSaveAndExit}
        onDiscardAndExit={handleDiscardAndExit}
        onCancelExit={handleCancelExit}
        getPatTypeColor={getPatTypeColor}
        getAchievement={getAchievement}
        calculateTotal={calculateTotal}
        isReadOnly={isCurrentAssessmentReadOnly}
        canFinalize={!finalizeDisabledReason}
        finalizeDisabledReason={finalizeDisabledReason}
        onFinalize={handleFinalize}
        isShareActive={isCurrentAssessmentShareActive}
        testsVisible={testsVisible}
        canShare={testsVisible && !isProfileLoading && isCurrentAssessmentPersisted && !hasUnsavedChanges}
        shareDisabledReason={shareDisabledReason}
        onShare={handleShareFromDetail}
        onRevokeShare={handleRevokeShareFromDetail}
      />
    );
  }

  if (activeTab === 'analysis') {
    return (
      <AnalysisTab
        assessments={visibleAssessments}
        selectedPatType={selectedPatType}
        onPatTypeChange={setSelectedPatType}
        patTypes={visiblePatTypes}
        user={user}
      />
    );
  }

  return (
    <PatList
      patTypes={visiblePatTypes}
      assessments={visibleAssessments}
      overview={<LiveOverview assessments={visibleAssessments} />}
      assessmentShareTokens={assessmentShareTokens}
      testsVisible={testsVisible}
      selectedPatType={selectedPatType}
      onPatTypeChange={setSelectedPatType}
      onCreate={(patType) => {
        createNewAssessment(patType);
        setShowList(false);
      }}
      onEdit={(assessment) => {
        openAssessment(assessment);
        setShowList(false);
      }}
      onDelete={deleteAssessment}
      getPatTypeColor={getPatTypeColor}
      getAchievement={getAchievement}
    />
  );
}
