import { useState, useCallback } from 'react';
import axios from 'axios';
import { t } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { WeekInfo } from '../types/shift';
import { handleApiError } from '../utils/errorHandler';
import { getISOWeek } from '../utils/weekUtils';
import { useToast } from '../components/shared/ToastProvider';

interface Plan {
  zp_id: number;
  zp_name: string;
  zp_description?: string;
  zp_week_count?: number;
  shifts_count: number;
  department?: { ber_name: string };
}

interface UseShiftPlanOptions {
  weekInfo: WeekInfo;
  selectedDepartment: number | '';
  onPlanApplied: () => void;
  confirm: (options: { title: string; message: string; color?: 'error' | 'primary' | 'warning' }) => Promise<boolean>;
}

interface UseShiftPlanReturn {
  // State
  plans: Plan[];
  planName: string;
  setPlanName: (name: string) => void;
  planDescription: string;
  setPlanDescription: (desc: string) => void;
  planWeekCount: number;
  setPlanWeekCount: (count: number) => void;
  planError: string;
  setPlanError: (error: string) => void;
  includeUserAssignments: boolean;
  setIncludeUserAssignments: (include: boolean) => void;
  editingPlan: Plan | null;
  editPlanName: string;
  setEditPlanName: (name: string) => void;

  // Dialog state
  savePlanDialogOpen: boolean;
  setSavePlanDialogOpen: (open: boolean) => void;
  applyPlanDialogOpen: boolean;
  setApplyPlanDialogOpen: (open: boolean) => void;
  editPlanDialogOpen: boolean;
  setEditPlanDialogOpen: (open: boolean) => void;

  // Actions
  loadPlans: () => Promise<void>;
  handleOpenSavePlanDialog: () => void;
  handleOpenApplyPlanDialog: () => Promise<void>;
  handleSavePlan: () => Promise<void>;
  handleApplyPlan: (planId: number) => Promise<void>;
  handleDeletePlan: (planId: number, planName: string, event: React.MouseEvent) => Promise<void>;
  handleOpenEditPlanDialog: (plan: Plan, event: React.MouseEvent) => void;
  handleUpdatePlanName: () => Promise<void>;

  // Utility
  formatWeekRange: (startYear: number, startWeek: number, weekCount: number) => string;
}

export function useShiftPlan(options: UseShiftPlanOptions): UseShiftPlanReturn {
  const { weekInfo, selectedDepartment, onPlanApplied, confirm } = options;
  const { i18n } = useLingui();
  const toast = useToast();

  // State
  const [plans, setPlans] = useState<Plan[]>([]);
  const [planName, setPlanName] = useState('');
  const [planDescription, setPlanDescription] = useState('');
  const [planWeekCount, setPlanWeekCount] = useState(1);
  const [planError, setPlanError] = useState('');
  const [includeUserAssignments, setIncludeUserAssignments] = useState(true);
  const [editingPlan, setEditingPlan] = useState<Plan | null>(null);
  const [editPlanName, setEditPlanName] = useState('');

  // Dialog state
  const [savePlanDialogOpen, setSavePlanDialogOpen] = useState(false);
  const [applyPlanDialogOpen, setApplyPlanDialogOpen] = useState(false);
  const [editPlanDialogOpen, setEditPlanDialogOpen] = useState(false);

  // Helper function to format week range considering year boundaries
  const formatWeekRange = useCallback(
    (startYear: number, startWeek: number, weekCount: number): string => {
      if (weekCount === 1) {
        return `KW ${startWeek}`;
      }

      const lastWeekOfYear = getISOWeek(new Date(startYear, 11, 28));
      const endWeekNum = startWeek + weekCount - 1;

      if (endWeekNum > lastWeekOfYear) {
        const weeksInCurrentYear = lastWeekOfYear - startWeek + 1;
        const weeksInNextYear = weekCount - weeksInCurrentYear;

        const currentYearPart =
          weeksInCurrentYear === 1
            ? `KW ${startWeek} (${startYear})`
            : `KW ${startWeek}-${lastWeekOfYear} (${startYear})`;

        const nextYearPart =
          weeksInNextYear === 1
            ? `KW 1 (${startYear + 1})`
            : `KW 1-${weeksInNextYear} (${startYear + 1})`;

        return `${currentYearPart}, ${nextYearPart}`;
      }

      return `KW ${startWeek}-${endWeekNum}`;
    },
    []
  );

  const loadPlans = useCallback(async () => {
    try {
      const params: any = {};
      if (selectedDepartment) {
        params.ber_id = selectedDepartment;
      }
      const response = await axios.get('/zeiterfassung/plans', { params });
      setPlans(response.data);
    } catch (error) {
      console.error('Error loading plans:', error);
      setPlanError(handleApiError('loading plans', error));
    }
  }, [selectedDepartment]);

  const handleOpenSavePlanDialog = useCallback(() => {
    setPlanName('');
    setPlanDescription('');
    setPlanError('');
    setSavePlanDialogOpen(true);
  }, []);

  const handleOpenApplyPlanDialog = useCallback(async () => {
    setPlanError('');
    setApplyPlanDialogOpen(true);
    await loadPlans();
  }, [loadPlans]);

  const handleSavePlan = useCallback(async () => {
    if (!planName.trim()) {
      setPlanError(i18n._(t`Bitte geben Sie einen Plan-Namen ein`));
      return;
    }

    if (!selectedDepartment) {
      setPlanError(i18n._(t`Bitte wählen Sie einen Bereich aus`));
      return;
    }

    try {
      const response = await axios.post('/zeiterfassung/plans/save-current', {
        year: weekInfo.year,
        week: weekInfo.week,
        zp_name: planName.trim(),
        zp_description: planDescription,
        zp_ber_id: selectedDepartment,
        zp_week_count: planWeekCount,
      });

      setSavePlanDialogOpen(false);
      setPlanName('');
      setPlanDescription('');
      setPlanWeekCount(1);
      setPlanError('');

      if (response.data.name_changed) {
        toast.warning({ title: i18n._(t`Plan gespeichert`), description: i18n._(t`Gespeichert als "${response.data.final_name}" (Name war bereits vergeben)`) });
      } else {
        toast.success({ title: i18n._(t`Plan "${response.data.plan.zp_name}" erfolgreich gespeichert`) });
      }
    } catch (error: any) {
      setPlanError(handleApiError('saving plan', error));
    }
  }, [planName, planDescription, planWeekCount, selectedDepartment, weekInfo, i18n]);

  const handleApplyPlan = useCallback(
    async (planId: number) => {
      try {
        await axios.post(`/zeiterfassung/plans/${planId}/apply`, {
          year: weekInfo.year,
          week: weekInfo.week,
          include_user_assignments: includeUserAssignments,
        });

        setApplyPlanDialogOpen(false);
        onPlanApplied();
      } catch (error: any) {
        setPlanError(handleApiError('applying plan', error));
      }
    },
    [weekInfo, includeUserAssignments, onPlanApplied]
  );

  const handleDeletePlan = useCallback(
    async (planId: number, planNameToDelete: string, event: React.MouseEvent) => {
      event.stopPropagation();

      const confirmed = await confirm({
        title: i18n._(t`Plan löschen`),
        message: i18n._(t`Möchten Sie den Plan "${planNameToDelete}" wirklich löschen?`),
        color: 'error',
      });
      if (confirmed) {
        try {
          await axios.delete(`/zeiterfassung/plans/${planId}`);
          loadPlans();
          toast.success({ title: i18n._(t`Plan "${planNameToDelete}" gelöscht`) });
        } catch (error: any) {
          setPlanError(handleApiError('deleting plan', error));
        }
      }
    },
    [confirm, i18n, loadPlans]
  );

  const handleOpenEditPlanDialog = useCallback((plan: Plan, event: React.MouseEvent) => {
    event.stopPropagation();
    setEditingPlan(plan);
    setEditPlanName(plan.zp_name);
    setPlanError('');
    setEditPlanDialogOpen(true);
  }, []);

  const handleUpdatePlanName = useCallback(async () => {
    if (!editPlanName.trim()) {
      setPlanError(i18n._(t`Bitte geben Sie einen Plan-Namen ein`));
      return;
    }

    if (!editingPlan) return;

    try {
      await axios.put(`/zeiterfassung/plans/${editingPlan.zp_id}`, {
        zp_name: editPlanName.trim(),
      });

      setEditPlanDialogOpen(false);
      setEditingPlan(null);
      setEditPlanName('');
      setPlanError('');
      loadPlans();
      toast.success({ title: i18n._(t`Plan erfolgreich umbenannt`) });
    } catch (error: any) {
      setPlanError(handleApiError('updating plan', error));
    }
  }, [editPlanName, editingPlan, i18n, loadPlans]);

  return {
    plans,
    planName,
    setPlanName,
    planDescription,
    setPlanDescription,
    planWeekCount,
    setPlanWeekCount,
    planError,
    setPlanError,
    includeUserAssignments,
    setIncludeUserAssignments,
    editingPlan,
    editPlanName,
    setEditPlanName,
    savePlanDialogOpen,
    setSavePlanDialogOpen,
    applyPlanDialogOpen,
    setApplyPlanDialogOpen,
    editPlanDialogOpen,
    setEditPlanDialogOpen,
    loadPlans,
    handleOpenSavePlanDialog,
    handleOpenApplyPlanDialog,
    handleSavePlan,
    handleApplyPlan,
    handleDeletePlan,
    handleOpenEditPlanDialog,
    handleUpdatePlanName,
    formatWeekRange,
  };
}

export default useShiftPlan;
