import { Feather } from "@expo/vector-icons";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import DateTimePicker from "@react-native-community/datetimepicker";
import * as Haptics from "expo-haptics";
import { Image } from "expo-image";
import * as ImagePicker from "expo-image-picker";
import { File } from "expo-file-system";
import { fetch as expoFetch } from "expo/fetch";
import React, { useState } from "react";
import {
  ActivityIndicator,
  Alert,
  Platform,
  ScrollView,
  StyleSheet,
  Switch,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from "react-native";
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { ChannelChip } from "@/components/ChannelChip";
import { PostizIntegration, PostizUploadResult, usePostiz } from "@/context/PostizContext";
import { useColors } from "@/hooks/useColors";

export default function ComposeScreen() {
  const colors = useColors();
  const insets = useSafeAreaInsets();
  const { client, isConfigured, apiKey, baseUrl } = usePostiz();
  const queryClient = useQueryClient();

  const [content, setContent] = useState("");
  const [selectedChannels, setSelectedChannels] = useState<string[]>([]);
  const [postNow, setPostNow] = useState(false);
  const [scheduleDate, setScheduleDate] = useState(
    () => new Date(Date.now() + 60 * 60 * 1000)
  );
  const [showDatePicker, setShowDatePicker] = useState(false);
  const [showTimePicker, setShowTimePicker] = useState(false);
  const [imageUri, setImageUri] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  const { data: integrations, isLoading: loadingIntegrations } =
    useQuery<PostizIntegration[]>({
      queryKey: ["integrations"],
      queryFn: async () => {
        if (!client) return [];
        const res = await client.get("/integrations");
        return Array.isArray(res.data) ? res.data : res.data?.integrations ?? [];
      },
      enabled: !!client,
      staleTime: 60000,
    });

  const toggleChannel = (id: string) => {
    setSelectedChannels((prev) =>
      prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id]
    );
  };

  const pickImage = async () => {
    const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (status !== "granted") {
      Alert.alert("Permission required", "Allow access to your photo library.");
      return;
    }
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ["images"],
      allowsEditing: false,
      quality: 0.85,
    });
    if (!result.canceled && result.assets[0]) {
      setImageUri(result.assets[0].uri);
    }
  };

  const removeImage = () => setImageUri(null);

  const uploadImage = async (): Promise<PostizUploadResult | null> => {
    if (!imageUri) return null;
    setUploading(true);
    try {
      const formData = new FormData();
      if (Platform.OS === "web") {
        const response = await expoFetch(imageUri);
        const blob = await response.blob();
        formData.append("file", blob, "upload.jpg");
      } else {
        const file = new File(imageUri);
        formData.append("file", file as unknown as Blob);
      }
      const uploadRes = await expoFetch(`${baseUrl}/upload`, {
        method: "POST",
        headers: { Authorization: apiKey },
        body: formData,
      });
      const data = await uploadRes.json() as PostizUploadResult;
      return data;
    } catch (e) {
      Alert.alert("Upload Failed", "Could not upload image. Please try again.");
      return null;
    } finally {
      setUploading(false);
    }
  };

  const handleSubmit = async () => {
    if (!client) return;
    if (!content.trim()) {
      Alert.alert("Empty post", "Please write something before posting.");
      return;
    }
    if (selectedChannels.length === 0) {
      Alert.alert("No channel", "Please select at least one channel.");
      return;
    }
    Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
    setSubmitting(true);
    try {
      let media: Array<{ id: string; path: string }> = [];
      if (imageUri) {
        const uploaded = await uploadImage();
        if (uploaded) {
          media = [{ id: uploaded.id, path: uploaded.path }];
        }
      }
      const payload = {
        type: postNow ? "now" : "schedule",
        date: postNow ? new Date().toISOString() : scheduleDate.toISOString(),
        content: [{ content: content.trim(), image: media }],
        integrations: selectedChannels,
      };
      await client.post("/posts", payload);
      Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
      Alert.alert(
        "Posted!",
        postNow ? "Your post has been published." : "Post scheduled successfully.",
        [{ text: "OK", onPress: resetForm }]
      );
      queryClient.invalidateQueries({ queryKey: ["posts"] });
      queryClient.invalidateQueries({ queryKey: ["posts-list"] });
    } catch (e) {
      Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
      Alert.alert("Failed", "Could not submit post. Please try again.");
    } finally {
      setSubmitting(false);
    }
  };

  const resetForm = () => {
    setContent("");
    setSelectedChannels([]);
    setPostNow(false);
    setImageUri(null);
    setScheduleDate(new Date(Date.now() + 60 * 60 * 1000));
  };

  const formatDateLabel = (d: Date) =>
    d.toLocaleDateString("en-US", {
      month: "short",
      day: "numeric",
      year: "numeric",
    });
  const formatTimeLabel = (d: Date) =>
    d.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });

  if (!isConfigured) {
    return (
      <View style={[styles.centered, { backgroundColor: colors.background }]}>
        <Feather name="lock" size={32} color={colors.mutedForeground} />
        <Text style={[styles.sectionTitle, { color: colors.foreground }]}>
          Not Configured
        </Text>
        <Text style={[styles.hint, { color: colors.mutedForeground }]}>
          Add your API key in Settings
        </Text>
      </View>
    );
  }

  return (
    <KeyboardAwareScrollView
      style={{ flex: 1, backgroundColor: colors.background }}
      contentContainerStyle={[
        styles.container,
        {
          paddingTop: Platform.OS === "web" ? 67 : 16,
          paddingBottom:
            Platform.OS === "web" ? 100 : insets.bottom + 80,
        },
      ]}
      bottomOffset={80}
      keyboardShouldPersistTaps="handled"
      showsVerticalScrollIndicator={false}
    >
      <View
        style={[
          styles.textArea,
          { backgroundColor: colors.card, borderColor: colors.border },
        ]}
      >
        <TextInput
          style={[styles.textInput, { color: colors.foreground }]}
          placeholder="What do you want to post?"
          placeholderTextColor={colors.mutedForeground}
          multiline
          value={content}
          onChangeText={setContent}
          maxLength={3000}
          textAlignVertical="top"
        />
        <Text style={[styles.charCount, { color: colors.mutedForeground }]}>
          {content.length}/3000
        </Text>
      </View>

      {imageUri && (
        <View style={styles.imagePreviewWrap}>
          <Image
            source={{ uri: imageUri }}
            style={[styles.imagePreview, { borderColor: colors.border }]}
            contentFit="cover"
          />
          <TouchableOpacity
            onPress={removeImage}
            style={[styles.removeImg, { backgroundColor: colors.destructive }]}
          >
            <Feather name="x" size={12} color="#fff" />
          </TouchableOpacity>
        </View>
      )}

      <TouchableOpacity
        onPress={pickImage}
        activeOpacity={0.7}
        style={[
          styles.mediaBtn,
          { backgroundColor: colors.card, borderColor: colors.border },
        ]}
      >
        <Feather name="image" size={16} color={colors.mutedForeground} />
        <Text style={[styles.mediaBtnText, { color: colors.mutedForeground }]}>
          {imageUri ? "Change image" : "Add image"}
        </Text>
      </TouchableOpacity>

      <Text style={[styles.sectionLabel, { color: colors.mutedForeground }]}>
        CHANNELS
      </Text>
      {loadingIntegrations ? (
        <ActivityIndicator color={colors.primary} style={{ marginVertical: 8 }} />
      ) : (integrations ?? []).length === 0 ? (
        <Text style={[styles.hint, { color: colors.mutedForeground }]}>
          No channels found. Add integrations in your Postiz instance.
        </Text>
      ) : (
        <ScrollView
          horizontal
          showsHorizontalScrollIndicator={false}
          contentContainerStyle={styles.channelList}
        >
          {(integrations ?? []).map((intg) => (
            <ChannelChip
              key={intg.id}
              integration={intg}
              selected={selectedChannels.includes(intg.id)}
              onToggle={() => toggleChannel(intg.id)}
            />
          ))}
        </ScrollView>
      )}

      <View
        style={[
          styles.scheduleRow,
          { backgroundColor: colors.card, borderColor: colors.border },
        ]}
      >
        <View style={styles.scheduleRowLeft}>
          <Feather name="zap" size={16} color={colors.primary} />
          <Text style={[styles.scheduleLabel, { color: colors.foreground }]}>
            Post now
          </Text>
        </View>
        <Switch
          value={postNow}
          onValueChange={setPostNow}
          trackColor={{ false: colors.muted, true: colors.primary }}
          thumbColor={colors.primaryForeground}
        />
      </View>

      {!postNow && (
        <View style={styles.dateTimeRow}>
          <TouchableOpacity
            onPress={() => {
              setShowTimePicker(false);
              setShowDatePicker((v) => !v);
            }}
            style={[
              styles.dateBtn,
              { backgroundColor: colors.card, borderColor: colors.border },
            ]}
            activeOpacity={0.7}
          >
            <Feather name="calendar" size={14} color={colors.primary} />
            <Text style={[styles.dateBtnText, { color: colors.foreground }]}>
              {formatDateLabel(scheduleDate)}
            </Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => {
              setShowDatePicker(false);
              setShowTimePicker((v) => !v);
            }}
            style={[
              styles.dateBtn,
              { backgroundColor: colors.card, borderColor: colors.border },
            ]}
            activeOpacity={0.7}
          >
            <Feather name="clock" size={14} color={colors.primary} />
            <Text style={[styles.dateBtnText, { color: colors.foreground }]}>
              {formatTimeLabel(scheduleDate)}
            </Text>
          </TouchableOpacity>
        </View>
      )}

      {showDatePicker && (
        <DateTimePicker
          value={scheduleDate}
          mode="date"
          display={Platform.OS === "ios" ? "spinner" : "default"}
          minimumDate={new Date()}
          textColor={colors.foreground}
          accentColor={colors.primary}
          onChange={(_: unknown, date?: Date) => {
            if (Platform.OS !== "ios") setShowDatePicker(false);
            if (date) {
              const merged = new Date(scheduleDate);
              merged.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
              setScheduleDate(merged);
            }
          }}
        />
      )}

      {showTimePicker && (
        <DateTimePicker
          value={scheduleDate}
          mode="time"
          display={Platform.OS === "ios" ? "spinner" : "default"}
          textColor={colors.foreground}
          accentColor={colors.primary}
          onChange={(_: unknown, date?: Date) => {
            if (Platform.OS !== "ios") setShowTimePicker(false);
            if (date) {
              const merged = new Date(scheduleDate);
              merged.setHours(date.getHours(), date.getMinutes());
              setScheduleDate(merged);
            }
          }}
        />
      )}

      <TouchableOpacity
        onPress={handleSubmit}
        activeOpacity={0.85}
        disabled={submitting || uploading}
        style={[
          styles.submitBtn,
          {
            backgroundColor:
              submitting || uploading ? colors.muted : colors.primary,
          },
        ]}
      >
        {submitting || uploading ? (
          <ActivityIndicator color={colors.primaryForeground} size="small" />
        ) : (
          <>
            <Feather
              name={postNow ? "send" : "clock"}
              size={16}
              color={colors.primaryForeground}
            />
            <Text style={[styles.submitText, { color: colors.primaryForeground }]}>
              {postNow ? "Publish Now" : "Schedule Post"}
            </Text>
          </>
        )}
      </TouchableOpacity>
    </KeyboardAwareScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    paddingHorizontal: 16,
    gap: 14,
  },
  centered: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    gap: 10,
  },
  textArea: {
    borderRadius: 14,
    borderWidth: 1,
    padding: 14,
    minHeight: 140,
  },
  textInput: {
    fontSize: 15,
    fontFamily: "Inter_400Regular",
    lineHeight: 22,
    minHeight: 100,
  },
  charCount: {
    fontSize: 11,
    fontFamily: "Inter_400Regular",
    alignSelf: "flex-end",
    marginTop: 4,
  },
  imagePreviewWrap: {
    position: "relative",
    alignSelf: "flex-start",
  },
  imagePreview: {
    width: 120,
    height: 120,
    borderRadius: 10,
    borderWidth: 1,
  },
  removeImg: {
    position: "absolute",
    top: 4,
    right: 4,
    width: 20,
    height: 20,
    borderRadius: 10,
    alignItems: "center",
    justifyContent: "center",
  },
  mediaBtn: {
    flexDirection: "row",
    alignItems: "center",
    gap: 8,
    paddingHorizontal: 14,
    paddingVertical: 10,
    borderRadius: 10,
    borderWidth: 1,
    alignSelf: "flex-start",
  },
  mediaBtnText: {
    fontSize: 13,
    fontFamily: "Inter_500Medium",
  },
  sectionLabel: {
    fontSize: 11,
    fontFamily: "Inter_600SemiBold",
    letterSpacing: 0.8,
    marginBottom: -6,
  },
  sectionTitle: {
    fontSize: 18,
    fontFamily: "Inter_600SemiBold",
  },
  hint: {
    fontSize: 13,
    fontFamily: "Inter_400Regular",
    textAlign: "center",
  },
  channelList: {
    flexDirection: "row",
    gap: 8,
    flexWrap: "wrap",
  },
  scheduleRow: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    paddingHorizontal: 16,
    paddingVertical: 12,
    borderRadius: 12,
    borderWidth: 1,
  },
  scheduleRowLeft: {
    flexDirection: "row",
    alignItems: "center",
    gap: 10,
  },
  scheduleLabel: {
    fontSize: 15,
    fontFamily: "Inter_500Medium",
  },
  dateTimeRow: {
    flexDirection: "row",
    gap: 10,
  },
  dateBtn: {
    flex: 1,
    flexDirection: "row",
    alignItems: "center",
    gap: 8,
    paddingHorizontal: 12,
    paddingVertical: 10,
    borderRadius: 10,
    borderWidth: 1,
  },
  dateBtnText: {
    fontSize: 13,
    fontFamily: "Inter_500Medium",
  },
  submitBtn: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    gap: 8,
    paddingVertical: 14,
    borderRadius: 14,
    marginTop: 4,
  },
  submitText: {
    fontSize: 15,
    fontFamily: "Inter_600SemiBold",
  },
});
