import { Feather } from "@expo/vector-icons";
import { useQuery } from "@tanstack/react-query";
import * as Clipboard from "expo-clipboard";
import * as Haptics from "expo-haptics";
import { router } from "expo-router";
import React, { useMemo, useState } from "react";
import {
  ActivityIndicator,
  Alert,
  FlatList,
  Platform,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
import { Calendar, DateData } from "react-native-calendars";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { PostizPost, usePostiz } from "@/context/PostizContext";
import { useColors } from "@/hooks/useColors";
import { StatusBadge } from "@/components/StatusBadge";
import { extractError } from "@/lib/extractError";

function formatDate(date: Date): string {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
}

function toDateKey(dateStr: string): string {
  try {
    return formatDate(new Date(dateStr));
  } catch {
    return dateStr.slice(0, 10);
  }
}

function formatPostTime(dateStr: string): string {
  try {
    const d = new Date(dateStr);
    return d.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });
  } catch {
    return "";
  }
}

export default function CalendarScreen() {
  const colors = useColors();
  const insets = useSafeAreaInsets();
  const { client, isConfigured } = usePostiz();

  const showContextMenu = (post: PostizPost) => {
    Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
    const preview = post.content.slice(0, 60) + (post.content.length > 60 ? "…" : "");
    const integrations = post.integrations ?? (post.integration ? [post.integration] : []);
    Alert.alert(
      post.state === "PUBLISHED" ? "Published post" :
      post.state === "QUEUE" ? "Scheduled post" :
      post.state === "ERROR" ? "Failed post" : "Draft",
      preview,
      [
        {
          text: "Copy text",
          onPress: () => {
            Clipboard.setStringAsync(post.content);
            Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
          },
        },
        {
          text: post.state === "PUBLISHED" ? "Repost" : "Edit",
          onPress: () =>
            router.push({
              pathname: "/(tabs)/compose",
              params: {
                prefillContent: post.content,
                prefillIntegrationIds: integrations.map((i) => i.id).join(","),
              },
            }),
        },
        { text: "Cancel", style: "cancel" },
      ]
    );
  };

  const now = new Date();
  const [currentMonth, setCurrentMonth] = useState({
    year: now.getFullYear(),
    month: now.getMonth() + 1,
  });
  const [selectedDay, setSelectedDay] = useState<string | null>(formatDate(now));

  const startDate = useMemo(() => {
    const d = new Date(currentMonth.year, currentMonth.month - 1, 1);
    return d.toISOString();
  }, [currentMonth]);

  const endDate = useMemo(() => {
    const d = new Date(currentMonth.year, currentMonth.month, 0, 23, 59, 59);
    return d.toISOString();
  }, [currentMonth]);

  const { data: posts, isLoading, error, refetch } = useQuery<PostizPost[]>({
    queryKey: ["posts", startDate, endDate, !!client],
    queryFn: async () => {
      if (!client) return [];
      const res = await client.get("posts", {
        params: { startDate, endDate },
      });
      return Array.isArray(res.data) ? res.data : res.data?.posts ?? [];
    },
    enabled: !!client,
    retry: 1,
    staleTime: 0,
  });

  const markedDates = useMemo(() => {
    const marks: Record<string, {
      dots?: Array<{ color: string }>;
      selected?: boolean;
      selectedColor?: string;
    }> = {};

    (posts ?? []).forEach((post) => {
      const key = toDateKey(post.publishDate);
      if (!marks[key]) marks[key] = { dots: [] };
      const dotColor =
        post.state === "PUBLISHED"
          ? colors.success
          : post.state === "ERROR"
          ? colors.error
          : colors.primary;
      marks[key].dots = [...(marks[key].dots ?? []), { color: dotColor }];
    });

    if (selectedDay) {
      marks[selectedDay] = {
        ...(marks[selectedDay] ?? {}),
        selected: true,
        selectedColor: colors.primary,
      };
    }
    return marks;
  }, [posts, selectedDay, colors]);

  const dayPosts = useMemo(() => {
    if (!selectedDay || !posts) return [];
    return posts.filter((p) => toDateKey(p.publishDate) === selectedDay);
  }, [posts, selectedDay]);

  if (!isConfigured) {
    return (
      <View style={[styles.centered, { backgroundColor: colors.background }]}>
        <Feather name="settings" size={32} color={colors.mutedForeground} />
        <Text style={[styles.emptyTitle, { color: colors.foreground }]}>
          Not Configured
        </Text>
        <Text style={[styles.emptyText, { color: colors.mutedForeground }]}>
          Add your API key in Settings to get started
        </Text>
        <TouchableOpacity
          style={[styles.btn, { backgroundColor: colors.primary }]}
          onPress={() => router.push("/(tabs)/settings")}
          activeOpacity={0.8}
        >
          <Text style={[styles.btnText, { color: colors.primaryForeground }]}>
            Open Settings
          </Text>
        </TouchableOpacity>
      </View>
    );
  }

  return (
    <View
      style={[
        styles.container,
        {
          backgroundColor: colors.background,
          paddingTop: Platform.OS === "web" ? 67 : 0,
          paddingBottom: Platform.OS === "web" ? 34 : 0,
        },
      ]}
    >
      <Calendar
        key={colors.background}
        theme={{
          backgroundColor: colors.background,
          calendarBackground: colors.background,
          textSectionTitleColor: colors.mutedForeground,
          selectedDayBackgroundColor: colors.primary,
          selectedDayTextColor: colors.primaryForeground,
          todayTextColor: colors.primary,
          dayTextColor: colors.foreground,
          textDisabledColor: colors.mutedForeground + "60",
          dotColor: colors.primary,
          selectedDotColor: colors.primaryForeground,
          arrowColor: colors.primary,
          monthTextColor: colors.foreground,
          indicatorColor: colors.primary,
          textDayFontFamily: "Inter_400Regular",
          textMonthFontFamily: "Inter_600SemiBold",
          textDayHeaderFontFamily: "Inter_500Medium",
          textDayFontSize: 14,
          textMonthFontSize: 16,
          textDayHeaderFontSize: 12,
        }}
        markingType="multi-dot"
        markedDates={markedDates}
        onDayPress={(day: DateData) => setSelectedDay(day.dateString)}
        onMonthChange={(month: DateData) => {
          setCurrentMonth({ year: month.year, month: month.month });
        }}
      />

      <View style={[styles.divider, { backgroundColor: colors.border }]} />

      {isLoading ? (
        <View style={styles.centered}>
          <ActivityIndicator color={colors.primary} />
        </View>
      ) : error ? (
        <View style={styles.centered}>
          <Feather name="alert-circle" size={24} color={colors.error} />
          <Text style={[styles.emptyText, { color: colors.mutedForeground }]}>
            Failed to load posts
          </Text>
          <Text style={[styles.emptyText, { color: colors.error, fontSize: 11 }]} selectable>
            {extractError(error)}
          </Text>
          <TouchableOpacity onPress={() => refetch()} style={styles.retryBtn}>
            <Text style={[styles.retryText, { color: colors.primary }]}>Retry</Text>
          </TouchableOpacity>
        </View>
      ) : (
        <FlatList
          data={dayPosts}
          keyExtractor={(item) => item.id}
          contentInsetAdjustmentBehavior="automatic"
          ListHeaderComponent={
            selectedDay ? (
              <View style={styles.dayHeader}>
                <Text style={[styles.dayHeaderText, { color: colors.mutedForeground }]}>
                  {new Date(selectedDay).toLocaleDateString("en-US", {
                    weekday: "long",
                    month: "long",
                    day: "numeric",
                  })}
                </Text>
                <Text style={[styles.countText, { color: colors.mutedForeground }]}>
                  {dayPosts.length} post{dayPosts.length !== 1 ? "s" : ""}
                </Text>
              </View>
            ) : null
          }
          ListEmptyComponent={
            <View style={styles.emptyDay}>
              <Text style={[styles.emptyDayText, { color: colors.mutedForeground }]}>
                No posts scheduled
              </Text>
              <TouchableOpacity
                onPress={() => router.push("/(tabs)/compose")}
                style={styles.composeHint}
              >
                <Feather name="plus-circle" size={14} color={colors.primary} />
                <Text style={[styles.composeHintText, { color: colors.primary }]}>
                  Create a post
                </Text>
              </TouchableOpacity>
            </View>
          }
          renderItem={({ item }) => (
            <TouchableOpacity
              style={[styles.dayPost, { borderBottomColor: colors.border }]}
              activeOpacity={0.7}
              onPress={() => showContextMenu(item)}
            >
              <View style={styles.dayPostLeft}>
                <Text style={[styles.timeText, { color: colors.primary }]}>
                  {formatPostTime(item.publishDate)}
                </Text>
                <Text
                  style={[styles.postContent, { color: colors.foreground }]}
                  numberOfLines={2}
                >
                  {item.content}
                </Text>
              </View>
              <StatusBadge status={item.state} />
            </TouchableOpacity>
          )}
          scrollEnabled={dayPosts.length > 0}
          showsVerticalScrollIndicator={false}
        />
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  centered: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    gap: 10,
    paddingHorizontal: 32,
  },
  emptyTitle: { fontSize: 18, fontFamily: "Inter_600SemiBold" },
  emptyText: { fontSize: 14, fontFamily: "Inter_400Regular", textAlign: "center" },
  btn: { marginTop: 8, paddingHorizontal: 20, paddingVertical: 10, borderRadius: 10 },
  btnText: { fontSize: 14, fontFamily: "Inter_600SemiBold" },
  divider: { height: StyleSheet.hairlineWidth },
  dayHeader: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    paddingHorizontal: 20,
    paddingVertical: 12,
  },
  dayHeaderText: { fontSize: 13, fontFamily: "Inter_500Medium" },
  countText: { fontSize: 12, fontFamily: "Inter_400Regular" },
  dayPost: {
    flexDirection: "row",
    alignItems: "flex-start",
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderBottomWidth: StyleSheet.hairlineWidth,
    gap: 12,
  },
  dayPostLeft: { flex: 1, gap: 4 },
  timeText: { fontSize: 12, fontFamily: "Inter_600SemiBold" },
  postContent: { fontSize: 13, fontFamily: "Inter_400Regular", lineHeight: 18 },
  emptyDay: { alignItems: "center", paddingTop: 32, gap: 10 },
  emptyDayText: { fontSize: 14, fontFamily: "Inter_400Regular" },
  composeHint: { flexDirection: "row", alignItems: "center", gap: 6 },
  composeHintText: { fontSize: 14, fontFamily: "Inter_500Medium" },
  retryBtn: { marginTop: 4 },
  retryText: { fontSize: 14, fontFamily: "Inter_500Medium" },
});
