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 = ["node-23.1.0", "nextjs:deno-2.0.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[];
  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 }),
  };
});
