import InputGroup from "@/components/auth/InputGroup";
import Button from "@/components/ui/Button";
import { useQueryMutation } from "@/hooks/mutate/useQueryMutation";
import { showToast } from "@/utils/toast";
import * as DocumentPicker from "expo-document-picker";
import { Controller, useForm } from "react-hook-form";
import { Platform, Text, TouchableOpacity, View } from "react-native";
import { useColor } from "@/hooks/useColor";
import {
  FileTextIcon,
  PaperclipIcon,
  PaperPlaneTiltIcon,
  XIcon,
} from "phosphor-react-native";

type ReplyTicketProps = {
  ticketNumber: string;
  refetch: () => void;
};

export type AttachmentType = {
  uri: string;
  name?: string;
  type?: string; // MIME type, e.g. "image/jpeg" or "application/pdf"
};

export type SupportReplyType = {
  message: string;
  attachments: AttachmentType[] | null;
  priority: "low" | "medium" | "high";
};

export default function ReplyTicket({
  ticketNumber,
  refetch,
}: ReplyTicketProps) {
  const { primary } = useColor();

  const {
    control,
    handleSubmit,
    reset,
    formState: { errors: formErrors },
  } = useForm<SupportReplyType>({
    defaultValues: {
      priority: "low",
      attachments: [],
    },
  });

  const {
    mutate,
    isLoading,
    backendErrors: errors,
  } = useQueryMutation({
    url: `/client/support-tickets/${ticketNumber}/replies`,
  });

  const onSubmit = handleSubmit((data: SupportReplyType) => {
    const hasAttachments = data.attachments && data.attachments.length > 0;

    if (hasAttachments) {
      const formData = new FormData();
      formData.append("message", data.message);

      data.attachments?.forEach((file, index) => {
        let fileUri = file.uri;
        if (Platform.OS === "android") {
          if (!fileUri.startsWith("file://") && !fileUri.startsWith("content://")) {
            fileUri = `file://${fileUri}`;
          }
          // content:// URIs are not uploadable via XHR on Android — DocumentPicker
          // with copyToCacheDirectory copies them, but ImagePicker may not.
          // Normalise to file:// by stripping the scheme and re-adding it.
          // If it's still content://, the upload will silently fail.
        }

        const safeName = (file.name || `attachment_${index}.jpg`).replace(/[^a-zA-Z0-9._-]/g, "_");
        formData.append("attachments[]", {
          uri: fileUri,
          name: safeName,
          type: file.type || "application/octet-stream",
        } as any);
      });

      mutate(formData, {
        onSuccess: async () => {
          showToast({ type: "success", text: "Replied successfully" });
          refetch();
          reset();
        },
        onError: (err) => {
          console.log("❌ Reply error (FormData):", err);
        },
      });
    } else {
      // Send as plain JSON if no attachments - much more stable in RN + Axios
      mutate(
        { message: data.message },
        {
          onSuccess: async () => {
            showToast({ type: "success", text: "Replied successfully" });
            refetch();
            reset();
          },
          onError: (err) => {
            console.log("❌ Reply error (JSON):", err);
          },
        },
      );
    }
  });

  return (
    <View className="mt-10 pt-10 border-t border-slate-100">
      <View className="flex-row items-center gap-x-2 mb-6">
        <View className="size-8 rounded-lg items-center justify-center bg-slate-100">
          <PaperPlaneTiltIcon size={18} color="#64748b" weight="duotone" />
        </View>
        <Text className="text-xl font-manrope-bold text-slate-800">
          Write a Reply
        </Text>
      </View>

      <View className="gap-y-6">
        <InputGroup
          control={control}
          multiline={true}
          label="Your Message"
          name="message"
          placeholder="Type your message here..."
          error={formErrors.message}
          backendError={errors?.message}
          numberOfLines={5}
        />

        <View>
          <View className="flex-row justify-between items-center mb-3">
            <Text className="text-base font-manrope-bold text-slate-800">
              Attachments
            </Text>
            <Text className="text-xs font-manrope-medium text-slate-400">
              Max 5MB per file
            </Text>
          </View>

          <Controller
            control={control}
            name={"attachments"}
            render={({ field: { onChange, value = [] } }) => (
              <View className="gap-y-3">
                <TouchableOpacity
                  activeOpacity={0.7}
                  onPress={async () => {
                    const res = await DocumentPicker.getDocumentAsync({
                      type: "*/*",
                      copyToCacheDirectory: true,
                    });

                    if (res.assets && res.assets.length > 0) {
                      const file = res.assets[0];
                      const fileObj = {
                        uri: file.uri,
                        name: file.name,
                        type: file.mimeType || "application/octet-stream",
                      };
                      onChange([...(value || []), fileObj]);
                    }
                  }}
                  className="flex-row items-center justify-center py-4 border-2 border-dashed border-slate-200 rounded-2xl bg-slate-50 gap-x-2"
                >
                  <PaperclipIcon size={20} color={primary.base} weight="bold" />
                  <Text className="font-manrope-bold text-slate-600">
                    Add Attachment
                  </Text>
                </TouchableOpacity>

                {value && value.length > 0 && (
                  <View className="gap-y-2 mt-2">
                    {value.map((file: AttachmentType, index: number) => (
                      <View
                        key={index}
                        className="flex-row items-center justify-between p-3 bg-white border border-slate-100 rounded-xl shadow-sm"
                      >
                        <View className="flex-row items-center gap-x-3 flex-1">
                          <View className="size-8 rounded-lg bg-primary/5 items-center justify-center">
                            <FileTextIcon
                              size={16}
                              color={primary.base}
                              weight="duotone"
                            />
                          </View>
                          <Text
                            className="text-sm font-manrope-medium text-slate-700 flex-1"
                            numberOfLines={1}
                          >
                            {file.name}
                          </Text>
                        </View>
                        <TouchableOpacity
                          onPress={() => {
                            const newValue = [...value];
                            newValue.splice(index, 1);
                            onChange(newValue);
                          }}
                          hitSlop={8}
                          className="size-8 items-center justify-center rounded-full active:bg-slate-50"
                        >
                          <View pointerEvents="none">
                            <XIcon size={16} color="#94a3b8" weight="bold" />
                          </View>
                        </TouchableOpacity>
                      </View>
                    ))}
                  </View>
                )}
              </View>
            )}
          />
        </View>

        <Button
          onPress={onSubmit}
          text="Send Reply"
          isLoading={isLoading}
          className="mt-4 h-14"
        />
      </View>
    </View>
  );
}
