import { v4 as uuidv4 } from "uuid";
import { create } from 'zustand';
import { addEdge, applyNodeChanges, applyEdgeChanges, Connection, EdgeChange, useNodes } from '@xyflow/react';
import {
  type Edge,
  type Node,
  type OnNodesChange,
  type OnEdgesChange,
  type OnConnect,
} from '@xyflow/react';
import { DeepPartial } from "react-hook-form";
import { Category, defaultCategories } from "./categories";
import { CreateValidators, Validator } from "./config";
import { z } from "zod";

export type InitData = {
  label: string;
  envVars: BoundEnvVar[];
  ports: Port[];
};

export type NodeData = InitData & {
  activeField?: string | undefined;
  state: string | null;
};

export type PortConnectedTo = {
  serviceId: string;
  portId: string;
}

export type NetworkData = NodeData & {
  domain: string;
};

export type NetworkNode = Node<NetworkData> & {
  type: "network";
};

export type GatewayHttpsData = NodeData & {
  network?: string;
  subdomain?: string;
  https?: PortConnectedTo;
};

export type GatewayHttpsNode = Node<GatewayHttpsData> & {
  type: "gateway-https";
};

export type GatewayTCPData = NodeData & {
  network?: string;
  subdomain?: string;
  exposed: PortConnectedTo[];
  selected?: {
    serviceId?: string;
    portId?: string;
  };
};

export type GatewayTCPNode = Node<GatewayTCPData> & {
  type: "gateway-tcp";
};

export type Port = {
  id: string;
  name: string;
  value: number;
};

export const ServiceTypes = [
  "deno:2.2.0",
  "golang:1.20.0",
  "golang:1.22.0",
  "golang:1.24.0",
  "hugo:latest",
  "php:8.2-apache",
  "nextjs:deno-2.0.0", 
  "node-23.1.0"
] as const;
export type ServiceType = typeof ServiceTypes[number];

export type ServiceData = NodeData & {
  type: ServiceType;
  repository: {
    id: string;
    branch: string;
    rootDir: string;
  };
  env: string[];
  volume: string[];
  preBuildCommands: string;
  isChoosingPortToConnect: boolean;
};

export type ServiceNode = Node<ServiceData> & {
  type: "app";
};

export type VolumeType = "ReadWriteOnce" | "ReadOnlyMany" | "ReadWriteMany" | "ReadWriteOncePod";

export type VolumeData = NodeData & {
  type: VolumeType;
  size: string;
  attachedTo: string[];
};

export type VolumeNode = Node<VolumeData> & {
  type: "volume";
};

export type PostgreSQLData = NodeData & {
  volumeId: string;
};

export type PostgreSQLNode = Node<PostgreSQLData> & {
  type: "postgresql";
};

export type MongoDBData = NodeData & {
  volumeId: string;
};

export type MongoDBNode = Node<MongoDBData> & {
  type: "mongodb";
};

export type GithubData = NodeData & {
  address: string;
};

export type GithubNode = Node<GithubData> & {
  type: "github";
};

export type NANode = Node<NodeData> & {
  type: undefined;
};

export type AppNode = NetworkNode | GatewayHttpsNode | GatewayTCPNode | ServiceNode | VolumeNode | PostgreSQLNode | MongoDBNode | GithubNode | NANode;

export function nodeLabel(n: AppNode): string {
  switch (n.type) {
    case "network": return n.data.domain;
    case "app": return n.data.label || "Service";
    case "github": return n.data.address || "Github";
    case "gateway-https": {
      if (n.data && n.data.network && n.data.subdomain) {
        return `https://${n.data.subdomain}.${n.data.network}`;
      } else {
        return "HTTPS Gateway";
      }
    }
    case "gateway-tcp": {
      if (n.data && n.data.network && n.data.subdomain) {
        return `${n.data.subdomain}.${n.data.network}`;
      } else {
        return "TCP Gateway";
      }
    }
    case "mongodb": return n.data.label || "MongoDB";
    case "postgresql": return n.data.label || "PostgreSQL";
    case "volume": return n.data.label || "Volume";
    case undefined: throw new Error("MUST NOT REACH!");
  }
}

export function nodeIsConnectable(n: AppNode, handle: string): boolean {
  switch (n.type) {
    case "network":
      return true;
    case "app":
      if (handle === "ports") {
        return n.data !== undefined && n.data.ports !== undefined && n.data.ports.length > 0;
      } else if (handle === "repository") {
        if (!n.data || !n.data.repository || !n.data.repository.id) {
            return true;
        }
        return false;
      }
      return false;   
    case "github":
      if (n.data !== undefined && n.data.address) {
        return true;
      }
      return false;
    case "gateway-https":
      if (handle === "subdomain") {
        return n.data.network === undefined;
      }
      return n.data === undefined || n.data.https === undefined;
    case "gateway-tcp":
      if (handle === "subdomain") {
        return n.data.network === undefined;
      }
      return true;
    case "mongodb":
      return true;
    case "postgresql":
      return true;
    case "volume":
      if (n.data === undefined || n.data.type === undefined) {
        return false;
      }
      if (n.data.type === "ReadWriteOnce" || n.data.type === "ReadWriteOncePod") {
          return n.data.attachedTo === undefined || n.data.attachedTo.length === 0;
      }
      return true;
    case undefined: throw new Error("MUST NOT REACH!");
  }
}

export type BoundEnvVar = {
  id: string;
  source: string | null;
} | {
  id: string;
  source: string | null;
  name: string;
  isEditting: boolean;
} | {
  id: string;
  source: string | null;
  name: string;
  alias: string;
  isEditting: boolean;
} | {
  id: string;
  source: string | null;
  portId: string;
  name: string;
  alias: string;
  isEditting: boolean;
};

export type EnvVar = {
  name: string;
  value: string;
};

export function nodeEnvVarNamePort(n: AppNode, portName: string): string {
  return `DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS_${portName.toUpperCase()}`;
}

export function nodeEnvVarNames(n: AppNode): string[] {
  switch (n.type) {
    case "app": return [
      `DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS`, 
      ...(n.data.ports || []).map((p) => nodeEnvVarNamePort(n, p.name)),
    ];
    case "github": return [];
    case "gateway-https": return [];
    case "gateway-tcp": return [];
    case "mongodb": return [`DODO_MONGODB_${n.data.label.toUpperCase()}_URL`];
    case "postgresql": return [`DODO_POSTGRESQL_${n.data.label.toUpperCase()}_URL`];
    case "volume": return [`DODO_VOLUME_${n.data.label.toUpperCase()}_PATH`];
    case undefined: throw new Error("MUST NOT REACH");
  }
}

export type NodeType = Exclude<Pick<AppNode, "type">["type"], undefined>;

export type MessageType = "INFO" | "WARNING" | "FATAL";

export type Message = {
  id: string;
  type: MessageType;
  nodeId?: string;
  message: string;
  onHighlight?: (state: AppState) => void;
  onLooseHighlight?: (state: AppState) => void;
  onClick?: (state: AppState) => void;
};

export const envSchema = z.object({
  deployKey: z.string(),
  networks: z.array(z.object({
    name: z.string(),
    domain: z.string(),
  })),
});

export type Env = z.infer<typeof envSchema>;

export type Project = {
  id: string;
  name: string;
}

export type AppState = {
  projectId: string | undefined;
  projects: Project[];
  nodes: AppNode[];
  edges: Edge[];
  categories: Category[];
  messages: Message[];
  env?: Env;
  setHighlightCategory: (name: string, active: boolean) => void;
  onNodesChange: OnNodesChange<AppNode>;
  onEdgesChange: OnEdgesChange;
  onConnect: OnConnect;
  setNodes: (nodes: AppNode[]) => void;
  setEdges: (edges: Edge[]) => void;
  setProject: (projectId: string | undefined) => void;
  setProjects: (projects: Project[]) => void;
  updateNode: <T extends NodeType>(id: string, data: DeepPartial<(AppNode & (Pick<AppNode, "type"> | { type: T }))>) => void;
  updateNodeData: <T extends NodeType>(id: string, data: DeepPartial<(AppNode & (Pick<AppNode, "type"> | { type: T }))["data"]>) => void;
  replaceEdge: (c: Connection, id?: string) => void;
  refreshEnv: () => Promise<Env | undefined>;
};

const projectIdSelector = (state: AppState) => state.projectId;
const categoriesSelector = (state: AppState) => state.categories;
const messagesSelector = (state: AppState) => state.messages;
const envSelector = (state: AppState) => state.env;

export function useProjectId(): string | undefined {
  return useStateStore(projectIdSelector);
}

export function useCategories(): Category[] {
  return useStateStore(categoriesSelector);
}

export function useMessages(): Message[] {
  return useStateStore(messagesSelector);
}

export function useNodeMessages(id: string): Message[] {
  return useMessages().filter((m) => m.nodeId === id);
}

export function useNodeLabel(id: string): string {
  return nodeLabel(useNodes<AppNode>().find((n) => n.id === id)!);
}

export function useNodePortName(id: string, portId: string): string {
  return (useNodes<AppNode>().find((n) => n.id === id)!.data.ports || []).find((p) => p.id === portId)!.name;
}

let envRefresh: Promise<Env | undefined> | null = null;

const fixedEnv: Env = {
  "deployKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPK58vMu0MwIzdZT+mqpIBkhl48p9+/YwDCZv7MgTesF",
  "networks": [{
    "name": "Public",
    "domain": "v1.dodo.cloud",
  }, {
    "name": "Private",
    "domain": "p.v1.dodo.cloud",
  }],
};

export function useEnv(): Env {
  return fixedEnv;
  const store = useStateStore();
  const env = envSelector(store);
  console.log(env);
  if (env != null) {
    return env;
  }
  if (envRefresh == null) {
    envRefresh = store.refreshEnv();
    envRefresh.finally(() => envRefresh = null);
  }
  return {
    deployKey: "",
    networks: [],
  };
}

const v: Validator = CreateValidators();

export const useStateStore = create<AppState>((set, get): AppState => {
  set({ env: {
    "deployKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPK58vMu0MwIzdZT+mqpIBkhl48p9+/YwDCZv7MgTesF",
    "networks": [{
      "name": "Public",
      "domain": "v1.dodo.cloud",
    }, {
      "name": "Private",
      "domain": "p.v1.dodo.cloud",
    }],
  }});
  console.log(get().env);
  const setN = (nodes: AppNode[]) => {
    set({
      nodes: nodes,
      messages: v(nodes),
    })
  };
  function updateNodeData<T extends NodeType>(id: string, d: DeepPartial<(AppNode & (Pick<AppNode, "type"> | { type: T }))["data"]>): void {
    setN(get().nodes.map((n) => {
        if (n.id !== id) {
          return n;
        }
        const nd = {
          ...n,
          data: {
            ...n.data,
            ...d,
          },
        };
        return nd;
      })
    );
  };
  function updateNode<T extends NodeType>(id: string, d: DeepPartial<(AppNode & (Pick<AppNode, "type"> | { type: T }))>): void {
    setN(
      get().nodes.map((n) => {
        if (n.id !== id) {
          return n;
        }
        return {
          ...n,
          ...d,
        };
      })
    );
  };
  function onConnect(c: Connection) {
    const { nodes, edges } = get();
    set({
      edges: addEdge(c, edges),
    });
    const sn = nodes.filter((n) => n.id === c.source)[0]!;
    const tn = nodes.filter((n) => n.id === c.target)[0]!;
    if (tn.type === "network") {
      if (sn.type === "gateway-https") {
        updateNodeData<"gateway-https">(sn.id, {
          network: tn.data.domain,
        });
      }else if (sn.type === "gateway-tcp") {
        updateNodeData<"gateway-tcp">(sn.id, {
          network: tn.data.domain,
        });
      }
    }
    if (c.sourceHandle === "env_var" && c.targetHandle === "env_var") {
      const sourceEnvVars = nodeEnvVarNames(sn);
      if (sourceEnvVars.length === 0) {
        throw new Error("MUST NOT REACH!");
      }
      const id = uuidv4();
      if (sourceEnvVars.length === 1) {
        updateNode(c.target, {
          ...tn,
          data: {
            ...tn.data,
            envVars: [
              ...(tn.data.envVars || []),
              {
                id: id,
                source: c.source,
                name: sourceEnvVars[0],
                isEditting: false,
              },
            ],
          },
        });
      } else {
        updateNode(c.target, {
          ...tn,
          data: {
            ...tn.data,
            envVars: [
              ...(tn.data.envVars || []),
              {
                id: id,
                source: c.source,
              },
            ],
          },
        });
      }
    }
    if (c.sourceHandle === "ports" && c.targetHandle === "env_var") {
      const sourcePorts = sn.data.ports || [];
      const id = uuidv4();
      if (sourcePorts.length === 1) {
        updateNode(c.target, {
          ...tn,
          data: {
            ...tn.data,
            envVars: [
              ...(tn.data.envVars || []),
              {
                id: id,
                source: c.source,
                name: nodeEnvVarNamePort(sn, sourcePorts[0].name),
                portId: sourcePorts[0].id,
                isEditting: false,
              },
            ],
          },
        });
      }
    }
    if (c.sourceHandle === "volume") {
      updateNodeData<"volume">(c.source, {
        attachedTo: ((sn as VolumeNode).data.attachedTo || []).concat(c.source),
      });
    }
    if (c.targetHandle === "volume") {
      if (tn.type === "postgresql" || tn.type === "mongodb") {
        updateNodeData(c.target, {
          volumeId: c.source,
        });
      }
    }
    if (c.targetHandle === "https") {
      if ((sn.data.ports || []).length === 1) {
        updateNodeData<"gateway-https">(c.target, {
          https: {
            serviceId: c.source,
            portId: sn.data.ports![0].id,
          }
        });
      } else {
        updateNodeData<"gateway-https">(c.target, {
          https: {
            serviceId: c.source,
            portId: "", // TODO(gio)
          }
        });
      }
    }
    if (c.targetHandle === "tcp") {
      const td = tn.data as GatewayTCPData;
      if ((sn.data.ports || []).length === 1) {
        updateNodeData<"gateway-tcp">(c.target, {
          exposed: (td.exposed || []).concat({
            serviceId: c.source,
            portId: sn.data.ports![0].id,
          }),
        });
      } else {
        updateNodeData<"gateway-tcp">(c.target, {
          selected: {
            serviceId: c.source,
            portId: undefined,
          },
        });
      }
    }
    if (sn.type === "app") {
      if (c.sourceHandle === "ports") {
        updateNodeData<"app">(sn.id, {
          isChoosingPortToConnect: true,
        });
      }
    }
    if (tn.type === "app") {
      if (c.targetHandle === "repository") {
        updateNodeData<"app">(tn.id, {
          repository: {
            id: c.source,
            branch: "master",
            rootDir: "/",
          }
        });
      }
    }
  }
  return {
    projectId: undefined,
    projects: [],
    nodes: [],
    edges: [],
    categories: defaultCategories,
    messages: v([]),
    setHighlightCategory: (name, active) => {
      set({
        categories: get().categories.map(
          (c) => {
            if (c.title.toLowerCase() !== name.toLowerCase()) {
              return c;
            } else {
              return {
                ...c,
                active,
              }
            }
          })
      });
    },
    onNodesChange: (changes) => {
      const nodes = applyNodeChanges(changes, get().nodes);
      setN(nodes);
    },
    onEdgesChange: (changes) => {
      set({
        edges: applyEdgeChanges(changes, get().edges),
      });
    },
    setNodes: (nodes) => {
      setN(nodes);
    },
    setEdges: (edges) => {
      set({ edges });
    },
    replaceEdge: (c, id) => {
      let change: EdgeChange;
      if (id === undefined) {
        change = {
          type: "add",
          item: {
            id: uuidv4(),
            ...c,
          }
        };
        onConnect(c);
      } else {
        change = {
          type: "replace",
          id,
          item: {
            id,
            ...c,
          }
        };
      }
      set({
        edges: applyEdgeChanges([change], get().edges),
      })
    },
    updateNode,
    updateNodeData,
    onConnect,
    refreshEnv: async () => {
      return get().env;
        const resp = await fetch("/env");
        if (!resp.ok) {
          throw new Error("failed to fetch env config");
        }
        set({ env: envSchema.parse(await resp.json()) });
        return get().env;
    },
    setProject: (projectId) => set({ projectId }),
    setProjects: (projects) => set({ projects }),
  };
});
