import {
  View,
  Text,
  TextInput,
  Pressable,
  ActivityIndicator,
} from "react-native";
import { Frequency, rrulestr } from "rrule";
import BaseBackground from "../components/BaseBackground";
import { useThemeStore } from "../stores/ThemeStore";
import { useCallback, useEffect, useState } from "react";
import { router, useLocalSearchParams } from "expo-router";
import Header, { HeaderButton } from "../components/Header";
import {
  DatePickerButton,
  TimePickerButton,
} from "../components/DateTimePicker";
import { Ionicons } from "@expo/vector-icons";
import { ScrollableDropdown } from "../components/ScrollableDropdown";
import { useDropdownPosition } from "../hooks/useDropdownPosition";
import { EventService, ChatService } from "../services";
import {
  buildRRule,
  CreateEventDTO,
  REPEAT_TYPE_LABELS,
  RepeatType,
} from "@calchat/shared";
import { useChatStore } from "../stores";
import CustomTextInput, {
  CustomTextInputProps,
} from "../components/CustomTextInput";

type EditEventTextFieldProps = CustomTextInputProps & {
  titel: string;
};

const EditEventTextField = (props: EditEventTextFieldProps) => {
  const { theme } = useThemeStore();

  return (
    <View className={props.className}>
      <Text className="text-xl" style={{ color: theme.textPrimary }}>
        {props.titel}
      </Text>
      <CustomTextInput
        className="flex-1 px-3 py-2"
        text={props.text}
        multiline={props.multiline}
        onValueChange={props.onValueChange}
      />
    </View>
  );
};

type PickerRowProps = {
  title: string;
  showLabels?: boolean;
  dateValue: Date;
  onDateChange: (date: Date) => void;
  onTimeChange: (date: Date) => void;
};

const PickerRow = ({
  showLabels,
  dateValue,
  title,
  onDateChange,
  onTimeChange,
}: PickerRowProps) => {
  const { theme } = useThemeStore();
  return (
    <View className="flex flex-row w-11/12 mt-4 items-end justify-between gap-x-2">
      <Text className="text-xl pb-2" style={{ color: theme.textPrimary }}>
        {title}
      </Text>
      <View className="flex flex-row w-10/12 gap-x-2">
        <DatePickerButton
          className="flex-1"
          label={showLabels ? "Datum" : undefined}
          value={dateValue}
          onChange={onDateChange}
        />
        <TimePickerButton
          className="flex-1"
          label={showLabels ? "Uhrzeit" : undefined}
          value={dateValue}
          onChange={onTimeChange}
        />
      </View>
    </View>
  );
};

type RepeatPressableProps = {
  focused: boolean;
  repeatType: RepeatType;
  setRepeatType: (repeatType: RepeatType) => void;
};

const RepeatPressable = ({
  focused,
  repeatType,
  setRepeatType,
}: RepeatPressableProps) => {
  const { theme } = useThemeStore();
  return (
    <Pressable
      className="px-4 py-2 rounded-lg border"
      style={{
        backgroundColor: focused ? theme.chatBot : theme.secondaryBg,
        borderColor: theme.borderPrimary,
      }}
      onPress={() => setRepeatType(repeatType)}
    >
      <Text style={{ color: focused ? theme.buttonText : theme.textPrimary }}>
        {repeatType}
      </Text>
    </Pressable>
  );
};

type RepeatSelectorProps = {
  repeatCount: number;
  onRepeatCountChange: (count: number) => void;
  repeatType: RepeatType;
  onRepeatTypeChange: (type: RepeatType) => void;
};

// Static data for repeat count dropdown (1-120)
const REPEAT_COUNT_DATA = Array.from({ length: 120 }, (_, i) => i + 1);

const RepeatSelector = ({
  repeatCount,
  onRepeatCountChange,
  repeatType,
  onRepeatTypeChange,
}: RepeatSelectorProps) => {
  const { theme } = useThemeStore();
  const dropdown = useDropdownPosition(2);

  const handleSelectCount = useCallback(
    (count: number) => {
      onRepeatCountChange(count);
      dropdown.close();
    },
    [onRepeatCountChange, dropdown],
  );

  const typeLabel = REPEAT_TYPE_LABELS[repeatType];

  return (
    <View className="mt-4">
      {/* Repeat Type Selection */}
      <View className="flex flex-row gap-2 mb-3">
        <RepeatPressable
          repeatType="Tag"
          setRepeatType={onRepeatTypeChange}
          focused={repeatType === "Tag"}
        />
        <RepeatPressable
          repeatType="Woche"
          setRepeatType={onRepeatTypeChange}
          focused={repeatType === "Woche"}
        />
        <RepeatPressable
          repeatType="Monat"
          setRepeatType={onRepeatTypeChange}
          focused={repeatType === "Monat"}
        />
        <RepeatPressable
          repeatType="Jahr"
          setRepeatType={onRepeatTypeChange}
          focused={repeatType === "Jahr"}
        />
      </View>

      {/* Repeat Count Selection */}
      <View className="flex flex-row items-center">
        <Text className="text-lg" style={{ color: theme.textPrimary }}>
          Alle{" "}
        </Text>
        <Pressable
          ref={dropdown.ref}
          className="px-4 py-2 rounded-lg border"
          style={{
            backgroundColor: theme.secondaryBg,
            borderColor: theme.borderPrimary,
          }}
          onPress={dropdown.open}
        >
          <Text className="text-lg" style={{ color: theme.textPrimary }}>
            {repeatCount}
          </Text>
        </Pressable>
        <Text className="text-lg" style={{ color: theme.textPrimary }}>
          {" "}
          {typeLabel}
        </Text>
      </View>

      {/* Count Dropdown */}
      <ScrollableDropdown
        visible={dropdown.visible}
        onClose={dropdown.close}
        position={{
          bottom: 12,
          left: 10,
          width: 100,
        }}
        data={REPEAT_COUNT_DATA}
        keyExtractor={(n) => String(n)}
        renderItem={(n, theme) => (
          <View
            className="w-full flex justify-center items-center py-2"
            style={{
              backgroundColor: n % 2 === 0 ? theme.primeBg : theme.secondaryBg,
            }}
          >
            <Text className="text-xl" style={{ color: theme.textPrimary }}>
              {n}
            </Text>
          </View>
        )}
        onSelect={handleSelectCount}
        heightRatio={0.4}
        initialScrollIndex={repeatCount - 1}
      />
    </View>
  );
};

type EditEventHeaderProps = {
  id?: string;
  mode?: "calendar" | "chat";
};

const EditEventHeader = ({ id, mode }: EditEventHeaderProps) => {
  const getTitle = () => {
    if (mode === "chat") return "Edit Proposal";
    return id ? "Edit Meeting" : "New Meeting";
  };

  return (
    <Header className="flex flex-row justify-center items-center">
      <HeaderButton
        className="absolute left-6"
        iconName="arrow-back-outline"
        iconSize={36}
        onPress={router.back}
      />
      <View className="h-full flex justify-center ml-4">
        <Text className="text-center text-3xl font-bold">{getTitle()}</Text>
      </View>
    </Header>
  );
};

type EditEventParams = {
  id?: string;
  date?: string;
  mode?: "calendar" | "chat";
  eventData?: string;
  proposalContext?: string;
};

type ProposalContext = {
  messageId: string;
  proposalId: string;
  conversationId: string;
};

const EditEventScreen = () => {
  const { id, date, mode, eventData, proposalContext } =
    useLocalSearchParams<EditEventParams>();
  const { theme } = useThemeStore();
  const updateMessage = useChatStore((state) => state.updateMessage);

  // Only show loading if we need to fetch from API (calendar mode with id)
  const [isLoading, setIsLoading] = useState(
    mode !== "chat" && !!id && !eventData,
  );

  // Initialize dates from URL parameter or use current time
  const initialDate = date ? new Date(date) : new Date();
  const initialEndDate = new Date(initialDate.getTime() + 60 * 60 * 1000);

  const [repeatVisible, setRepeatVisible] = useState(false);
  const [repeatCount, setRepeatCount] = useState(1);
  const [repeatType, setRepeatType] = useState<RepeatType>("Tag");
  const [startDate, setStartDate] = useState(initialDate);
  const [endDate, setEndDate] = useState(initialEndDate);
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");

  // Helper to populate form from event data
  const populateFormFromEvent = useCallback((event: CreateEventDTO) => {
    setStartDate(new Date(event.startTime));
    setEndDate(new Date(event.endTime));
    setTitle(event.title);
    if (event.description) {
      setDescription(event.description);
    }

    if (event.recurrenceRule) {
      setRepeatVisible(true);

      const rrule = rrulestr(event.recurrenceRule);
      if (rrule.options.interval) {
        setRepeatCount(rrule.options.interval);
      }
      switch (rrule.options.freq) {
        case Frequency.DAILY:
          setRepeatType("Tag");
          break;
        case Frequency.WEEKLY:
          setRepeatType("Woche");
          break;
        case Frequency.MONTHLY:
          setRepeatType("Monat");
          break;
        case Frequency.YEARLY:
          setRepeatType("Jahr");
          break;
      }
    }
  }, []);

  // Load event data based on mode
  useEffect(() => {
    // Chat mode: load from eventData JSON parameter
    if (mode === "chat" && eventData) {
      try {
        const event = JSON.parse(eventData) as CreateEventDTO;
        populateFormFromEvent(event);
      } catch (error) {
        console.error("Failed to parse eventData:", error);
      }
      return;
    }

    // Calendar mode with id: fetch from API
    if (id && !eventData) {
      const fetchEvent = async () => {
        try {
          const event = await EventService.getById(id);
          populateFormFromEvent({
            title: event.title,
            description: event.description,
            startTime: event.startTime,
            endTime: event.endTime,
            recurrenceRule: event.recurrenceRule,
          });
        } catch (error) {
          console.error("Failed to load event: ", error);
        } finally {
          setIsLoading(false);
        }
      };

      fetchEvent();
    }
  }, [id, mode, eventData, populateFormFromEvent]);

  if (isLoading) {
    return (
      <BaseBackground>
        <EditEventHeader id={id} mode={mode} />
        <View className="flex-1 justify-center items-center">
          <ActivityIndicator size="large" color={theme.chatBot} />
        </View>
      </BaseBackground>
    );
  }

  const handleStartDateChange = (date: Date) => {
    // Keep the time from startDate, update the date part
    const newStart = new Date(startDate);
    newStart.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
    setStartDate(newStart);

    // If end date is before new start date, adjust it
    if (endDate < newStart) {
      const newEnd = new Date(newStart);
      newEnd.setHours(newStart.getHours() + 1);
      setEndDate(newEnd);
    }
  };

  const handleStartTimeChange = (date: Date) => {
    // Keep the date from startDate, update the time part
    const newStart = new Date(startDate);
    newStart.setHours(date.getHours(), date.getMinutes(), 0, 0);
    setStartDate(newStart);

    // If end time is before new start time on the same day, adjust it
    if (endDate <= newStart) {
      const newEnd = new Date(newStart);
      newEnd.setHours(newStart.getHours() + 1);
      setEndDate(newEnd);
    }
  };

  const handleEndDateChange = (date: Date) => {
    // Keep the time from endDate, update the date part
    const newEnd = new Date(endDate);
    newEnd.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
    setEndDate(newEnd);
  };

  const handleEndTimeChange = (date: Date) => {
    // Keep the date from endDate, update the time part
    const newEnd = new Date(endDate);
    newEnd.setHours(date.getHours(), date.getMinutes(), 0, 0);
    setEndDate(newEnd);
  };

  const handleSave = async () => {
    const eventObject: CreateEventDTO = {
      title,
      description: description === "" ? undefined : description,
      startTime: startDate,
      endTime: endDate,
      recurrenceRule: repeatVisible
        ? buildRRule(repeatType, repeatCount)
        : undefined,
    };

    // Chat mode: update proposal on server and sync response to local store
    if (mode === "chat" && proposalContext) {
      try {
        const context = JSON.parse(proposalContext) as ProposalContext;

        // Persist to server - returns updated message with recalculated conflictingEvents
        const updatedMessage = await ChatService.updateProposalEvent(
          context.messageId,
          context.proposalId,
          eventObject,
        );

        // Update local ChatStore with server response (includes updated conflicts)
        if (updatedMessage?.proposedChanges) {
          updateMessage(context.messageId, {
            proposedChanges: updatedMessage.proposedChanges,
          });
        }

        router.back();
      } catch (error) {
        console.error("Failed to update proposal:", error);
      }
      return;
    }

    // Calendar mode: call API
    try {
      if (id) {
        await EventService.update(id, eventObject);
      } else {
        await EventService.create(eventObject);
      }
      router.back();
    } catch (error) {
      console.error("Creating/Updating event failed!", error);
    }
  };

  const getButtonText = () => {
    if (mode === "chat") {
      return "Fertig";
    }
    return id ? "Aktualisiere Termin" : "Erstelle neuen Termin";
  };

  return (
    <BaseBackground>
      <EditEventHeader id={id} mode={mode} />
      <View className="h-full flex items-center">
        {/* Date and Time */}
        <View className="w-11/12">
          <EditEventTextField
            className="h-16 mt-2"
            titel="Titel"
            text={title}
            onValueChange={setTitle}
          />
          <PickerRow
            title="Von"
            dateValue={startDate}
            onDateChange={handleStartDateChange}
            onTimeChange={handleStartTimeChange}
            showLabels
          />
          <PickerRow
            title="Bis"
            dateValue={endDate}
            onDateChange={handleEndDateChange}
            onTimeChange={handleEndTimeChange}
          />

          {/* TODO: Reminder */}

          {/* Notes */}
          <EditEventTextField
            className="h-64 mt-6"
            titel="Notizen"
            text={description}
            onValueChange={setDescription}
            multiline
          />

          {/* Repeat Toggle Button */}
          <Pressable
            className="flex flex-row w-1/3 h-10 mt-4 rounded-lg items-center justify-evenly"
            style={{
              backgroundColor: repeatVisible
                ? theme.chatBot
                : theme.secondaryBg,
              borderWidth: 1,
              borderColor: theme.borderPrimary,
            }}
            onPress={() => setRepeatVisible(!repeatVisible)}
          >
            <Ionicons
              name="repeat"
              size={24}
              color={repeatVisible ? theme.buttonText : theme.textPrimary}
            />
            <Text
              style={{
                color: repeatVisible ? theme.buttonText : theme.textPrimary,
              }}
            >
              Wiederholen
            </Text>
          </Pressable>

          {/* Repeat Selector (shown when toggle is active) */}
          {repeatVisible && (
            <RepeatSelector
              repeatCount={repeatCount}
              onRepeatCountChange={setRepeatCount}
              repeatType={repeatType}
              onRepeatTypeChange={setRepeatType}
            />
          )}
        </View>
      </View>

      {/* Send new or updated Event */}
      <View className="absolute bottom-16 w-full h-16">
        <Pressable
          className="flex flex-row justify-center items-center py-3"
          onPress={handleSave}
          style={{
            backgroundColor: theme.confirmButton,
          }}
        >
          {mode !== "chat" && (
            <Ionicons name="add-outline" size={24} color={theme.buttonText} />
          )}
          <Text
            style={{ color: theme.buttonText }}
            className="font-semibold ml-1"
          >
            {getButtonText()}
          </Text>
        </Pressable>
      </View>
    </BaseBackground>
  );
};

export default EditEventScreen;
