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;
  auth?: {
    enabled: boolean;
    groups: string[];
    noAuthPathPatterns: string[];
  }
};

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;
  } | {
    id: string;
    branch: string;
  } | {
    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 }),
  };
});
