import axios, { AxiosInstance } from "axios";
import * as SecureStore from "expo-secure-store";
import React, {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useState,
} from "react";

const WORKSPACES_KEY = "postiz_workspaces_v2";
const LEGACY_API_KEY = "postiz_api_key";
const LEGACY_BASE_URL = "postiz_base_url";

export const DEFAULT_BASE_URL = "https://postiz.gyozamancave.fr/api/public/v1";

export interface PostizWorkspace {
  id: string;
  name: string;
  apiKey: string;
  baseUrl: string;
}

export interface PostizIntegration {
  id: string;
  name: string;
  type: string;
  picture?: string;
  identifier?: string;
  internalType?: string;
}

export interface PostizMediaItem {
  id: string;
  path: string;
}

export interface PostizPost {
  id: string;
  content: string;
  state: "QUEUE" | "PUBLISHED" | "ERROR" | "DRAFT";
  publishDate: string;
  integration?: PostizIntegration;
  integrations?: PostizIntegration[];
  image?: PostizMediaItem[];
  group?: string;
  errorMessage?: string;
}

export interface PostizUploadResult {
  id: string;
  path: string;
}

interface PostizContextValue {
  workspaces: PostizWorkspace[];
  isConfigured: boolean;
  isLoading: boolean;
  clients: Record<string, AxiosInstance>;
  addWorkspace: (ws: Omit<PostizWorkspace, "id">) => Promise<void>;
  updateWorkspace: (ws: PostizWorkspace) => Promise<void>;
  removeWorkspace: (id: string) => Promise<void>;
  // backward compat for posts.tsx (first workspace)
  client: AxiosInstance | null;
  apiKey: string;
  baseUrl: string;
}

const PostizContext = createContext<PostizContextValue>({
  workspaces: [],
  isConfigured: false,
  isLoading: true,
  clients: {},
  addWorkspace: async () => {},
  updateWorkspace: async () => {},
  removeWorkspace: async () => {},
  client: null,
  apiKey: "",
  baseUrl: DEFAULT_BASE_URL,
});

function makeClient(ws: PostizWorkspace): AxiosInstance {
  const baseURL = ws.baseUrl.endsWith("/") ? ws.baseUrl : ws.baseUrl + "/";
  const instance = axios.create({
    baseURL,
    headers: { Authorization: ws.apiKey, "Content-Type": "application/json" },
    timeout: 15000,
  });
  instance.interceptors.request.use((config) => {
    console.log(">>> REQUEST:", config.method?.toUpperCase(), (config.baseURL ?? "") + (config.url ?? ""));
    return config;
  });
  return instance;
}

function buildClients(list: PostizWorkspace[]): Record<string, AxiosInstance> {
  return Object.fromEntries(list.map((ws) => [ws.id, makeClient(ws)]));
}

export function PostizProvider({ children }: { children: React.ReactNode }) {
  const [workspaces, setWorkspaces] = useState<PostizWorkspace[]>([]);
  const [clients, setClients] = useState<Record<string, AxiosInstance>>({});
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    (async () => {
      try {
        const stored = await SecureStore.getItemAsync(WORKSPACES_KEY);
        if (stored) {
          const list: PostizWorkspace[] = JSON.parse(stored);
          setWorkspaces(list);
          setClients(buildClients(list));
        } else {
          // Migrate legacy single-workspace config
          const legacyKey = await SecureStore.getItemAsync(LEGACY_API_KEY);
          const legacyUrl = await SecureStore.getItemAsync(LEGACY_BASE_URL);
          if (legacyKey) {
            const migrated: PostizWorkspace = {
              id: Date.now().toString(),
              name: "Default",
              apiKey: legacyKey,
              baseUrl: (legacyUrl || DEFAULT_BASE_URL).replace(/\/$/, ""),
            };
            const list = [migrated];
            await SecureStore.setItemAsync(WORKSPACES_KEY, JSON.stringify(list));
            setWorkspaces(list);
            setClients(buildClients(list));
          }
        }
      } catch {
      } finally {
        setIsLoading(false);
      }
    })();
  }, []);

  const persist = useCallback(async (list: PostizWorkspace[]) => {
    await SecureStore.setItemAsync(WORKSPACES_KEY, JSON.stringify(list));
    setWorkspaces(list);
    setClients(buildClients(list));
  }, []);

  const addWorkspace = useCallback(
    async (ws: Omit<PostizWorkspace, "id">) => {
      await persist([...workspaces, { ...ws, id: Date.now().toString() }]);
    },
    [workspaces, persist]
  );

  const updateWorkspace = useCallback(
    async (ws: PostizWorkspace) => {
      await persist(workspaces.map((w) => (w.id === ws.id ? ws : w)));
    },
    [workspaces, persist]
  );

  const removeWorkspace = useCallback(
    async (id: string) => {
      await persist(workspaces.filter((w) => w.id !== id));
    },
    [workspaces, persist]
  );

  const primaryWorkspace = workspaces[0] ?? null;

  return (
    <PostizContext.Provider
      value={{
        workspaces,
        isConfigured: workspaces.length > 0,
        isLoading,
        clients,
        addWorkspace,
        updateWorkspace,
        removeWorkspace,
        client: primaryWorkspace ? (clients[primaryWorkspace.id] ?? null) : null,
        apiKey: primaryWorkspace?.apiKey ?? "",
        baseUrl: primaryWorkspace?.baseUrl ?? DEFAULT_BASE_URL,
      }}
    >
      {children}
    </PostizContext.Provider>
  );
}

export function usePostiz() {
  return useContext(PostizContext);
}
