/**
 * Contacts Store - Platform-aware contact management
 *
 * Native (Android/iOS): Uses expo-contacts to access device contacts
 * Web: Gracefully degrades - contacts feature not available
 */
import { create } from "zustand";
import { Platform, Alert } from "react-native";
import { formatPhoneNumber, isValidPhoneNumber } from "../utils/phoneUtils";
import { awardFirstContactSyncPoints } from "../services/pointsService";

// Only import expo-contacts on native platforms
let Contacts: any = null;
if (Platform.OS !== "web") {
  Contacts = require("expo-contacts");
}

export interface Contact {
  id: string;
  name: string;
  firstName?: string;
  lastName?: string;
  phoneNumbers?: Array<{
    number: string;
    formattedNumber: string;
    isPrimary?: boolean;
    label?: string;
  }>;
  emails?: Array<{
    email: string;
    isPrimary?: boolean;
    label?: string;
  }>;
  imageAvailable?: boolean;
  image?: any;
}

interface ContactsState {
  // State
  contacts: Contact[];
  loading: boolean;
  error: string | null;
  hasPermission: boolean;
  isInitialized: boolean;
  isSupported: boolean; // New: indicates if contacts are supported on this platform

  // Actions
  setContacts: (contacts: Contact[]) => void;
  setLoading: (loading: boolean) => void;
  setError: (error: string | null) => void;
  setHasPermission: (hasPermission: boolean) => void;
  setIsInitialized: (isInitialized: boolean) => void;

  // Permission actions
  checkPermission: () => Promise<boolean>;
  requestPermission: () => Promise<void>;

  // Data actions
  loadContacts: () => Promise<void>;
  refreshContacts: () => Promise<void>;
  findContactByPhoneNumber: (phoneNumber: string) => Contact | null;

  // Initialize
  initialize: () => Promise<void>;
}

export const useContactsStore = create<ContactsState>((set, get) => ({
  // Initial state
  contacts: [],
  loading: false,
  error: null,
  hasPermission: false,
  isInitialized: false,
  isSupported: Platform.OS !== "web", // Contacts not supported on web

  // Setters
  setContacts: (contacts) => set({ contacts }),
  setLoading: (loading) => set({ loading }),
  setError: (error) => set({ error }),
  setHasPermission: (hasPermission) => set({ hasPermission }),
  setIsInitialized: (isInitialized) => set({ isInitialized }),

  // Check permission status
  checkPermission: async (): Promise<boolean> => {
    // Web: No permission needed (feature not available)
    if (Platform.OS === "web" || !Contacts) {
      set({ hasPermission: false, isSupported: false });
      return false;
    }

    try {
      const { status } = await Contacts.getPermissionsAsync();
      const granted = status === "granted";
      set({ hasPermission: granted });
      return granted;
    } catch (err) {
      console.error("Error checking contacts permission:", err);
      set({ error: "Failed to check contacts permission" });
      return false;
    }
  },

  // Request permission
  requestPermission: async (): Promise<void> => {
    // Web: Show message that contacts aren't supported
    if (Platform.OS === "web" || !Contacts) {
      set({ hasPermission: false, isSupported: false });
      console.log("Contacts not supported on web platform");
      return;
    }

    try {
      set({ error: null });

      const { status } = await Contacts.requestPermissionsAsync();

      if (status === "granted") {
        set({ hasPermission: true });
        await get().loadContacts();
      } else {
        set({ hasPermission: false, error: "Contacts permission denied" });

        Alert.alert(
          "Permission Required",
          "To show your contacts as potential recipients, please grant contacts permission in your device settings.",
          [{ text: "OK", style: "default" }]
        );
      }
    } catch (err) {
      console.error("Error requesting contacts permission:", err);
      set({ error: "Failed to request contacts permission" });
    }
  },

  // Load contacts from device
  loadContacts: async (): Promise<void> => {
    // Web: Skip loading
    if (Platform.OS === "web" || !Contacts) {
      set({ loading: false, contacts: [], isSupported: false });
      return;
    }

    try {
      set({ loading: true, error: null });

      const { data } = await Contacts.getContactsAsync({
        fields: [
          Contacts.Fields.ID,
          Contacts.Fields.Name,
          Contacts.Fields.FirstName,
          Contacts.Fields.LastName,
          Contacts.Fields.PhoneNumbers,
          Contacts.Fields.Emails,
          Contacts.Fields.ImageAvailable,
          Contacts.Fields.Image,
        ],
        sort: Contacts.SortTypes.FirstName,
      });

      // Filter and format contacts
      const formattedContacts: Contact[] = data
        .filter((contact: any) => {
          return (
            contact.name &&
            contact.phoneNumbers &&
            contact.phoneNumbers.length > 0 &&
            contact.phoneNumbers.some(
              (phone: any) => phone.number && isValidPhoneNumber(phone.number)
            )
          );
        })
        .map((contact: any) => ({
          id: contact.id || "",
          name: contact.name || "",
          firstName: contact.firstName,
          lastName: contact.lastName,
          phoneNumbers: contact.phoneNumbers
            ?.filter(
              (phone: any) => phone.number && isValidPhoneNumber(phone.number)
            )
            ?.map((phone: any) => ({
              number: formatPhoneNumber(phone.number || ""),
              formattedNumber: formatPhoneNumber(phone.number || ""),
              isPrimary: phone.isPrimary,
              label: phone.label,
            })),
          emails: contact.emails?.map((email: any) => ({
            email: email.email || "",
            isPrimary: email.isPrimary,
            label: email.label,
          })),
          imageAvailable: contact.imageAvailable,
          image: contact.image,
        }));

      set({ contacts: formattedContacts });
      console.log(`Loaded ${formattedContacts.length} contacts`);

      try {
        await awardFirstContactSyncPoints();
      } catch (error) {
        console.warn(
          "[ContactsStore] Failed to award contact sync points",
          error
        );
      }
    } catch (err) {
      console.error("Error loading contacts:", err);
      set({ error: "Failed to load contacts", contacts: [] });
    } finally {
      set({ loading: false });
    }
  },

  // Refresh contacts
  refreshContacts: async (): Promise<void> => {
    if (Platform.OS === "web") {
      return;
    }

    const permitted = await get().checkPermission();
    if (permitted) {
      await get().loadContacts();
    }
  },

  // Find contact by phone number
  findContactByPhoneNumber: (phoneNumber: string): Contact | null => {
    const { contacts } = get();
    const formattedNumber = formatPhoneNumber(phoneNumber);
    return (
      contacts.find((contact) =>
        contact.phoneNumbers?.some(
          (phone) => phone.formattedNumber === formattedNumber
        )
      ) || null
    );
  },

  // Initialize on mount
  initialize: async () => {
    // Web: Mark as initialized but skip permission/loading
    if (Platform.OS === "web") {
      set({ isInitialized: true, isSupported: false });
      return;
    }

    const permitted = await get().checkPermission();
    if (permitted) {
      await get().loadContacts();
    }
    set({ isInitialized: true });
  },
}));
