import { useMutation, useQuery } from "@tanstack/react-query";
import { useParams } from "react-router-dom";

import {
  exportOperationYaml,
  generateDraft,
  getOperation,
  getOperationVersion,
  importOperationYaml,
  listAuthProfiles,
} from "../../entities/operation/api";
import type { OperationTarget } from "../../entities/operation/types";
import { GrpcDescriptorPanel } from "../../features/grpc-descriptor/panel";
import { PublishOperationPanel } from "../../features/publish-operation/panel";
import { SampleUploadPanel } from "../../features/sample-upload/panel";
import { SchemaViewerPanel } from "../../features/schema-viewer/panel";
import { TestRunPanel } from "../../features/test-run/panel";
import { PageSection } from "../../shared/ui/page-section";

function describeTarget(target: OperationTarget) {
  switch (target.kind) {
    case "rest":
      return [
        ["Base URL", target.base_url],
        ["Method", target.method],
        ["Path", target.path_template],
      ] as const;
    case "graphql":
      return [
        ["Endpoint", target.endpoint],
        ["Operation", `${target.operation_type} ${target.operation_name}`],
        ["Response path", target.response_path],
      ] as const;
    case "grpc":
      return [
        ["Server", target.server_addr],
        ["Service", `${target.package}.${target.service}/${target.method}`],
        ["Descriptor ref", target.descriptor_ref],
      ] as const;
  }
}

function readObjectRecord(value: unknown) {
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
    return {};
  }

  return value as Record<string, unknown>;
}

function readExecutionHeaders(value: unknown) {
  const config = readObjectRecord(value);
  const headers = config.headers;

  if (headers === null || typeof headers !== "object" || Array.isArray(headers)) {
    return {};
  }

  return headers as Record<string, unknown>;
}

function draftSubtitle(target: OperationTarget) {
  switch (target.kind) {
    case "rest":
      return "Upload request and response JSON samples, then infer schema and mapping drafts.";
    case "graphql":
      return "Upload stable request and response samples for the fixed GraphQL operation contract.";
    case "grpc":
      return "Upload JSON samples or inspect descriptor-driven schemas before refining mappings.";
  }
}

export function OperationDetailPage() {
  const { operationId = "" } = useParams();
  const summaryQuery = useQuery({
    queryKey: ["operation-summary", operationId],
    queryFn: () => getOperation(operationId),
    enabled: operationId.length > 0,
  });
  const currentVersion = summaryQuery.data?.current_draft_version ?? 0;
  const versionQuery = useQuery({
    queryKey: ["operation-version", operationId, currentVersion],
    queryFn: () => getOperationVersion(operationId, currentVersion),
    enabled: operationId.length > 0 && currentVersion > 0,
  });
  const authProfilesQuery = useQuery({
    queryKey: ["auth-profiles"],
    queryFn: listAuthProfiles,
  });
  const draftMutation = useMutation({
    mutationFn: async () => generateDraft(operationId),
  });
  const exportMutation = useMutation({
    mutationFn: async () => exportOperationYaml(operationId, currentVersion),
  });
  const importMutation = useMutation({
    mutationFn: async (yamlText: string) => importOperationYaml(yamlText, "upsert"),
  });

  const snapshot = versionQuery.data?.snapshot;
  const exportedYaml = exportMutation.data;
  const targetRows = snapshot ? describeTarget(snapshot.target) : [];

  return (
    <div className="page-stack">
      <PageSection
        title={summaryQuery.data?.display_name ?? "Operation"}
        subtitle={
          summaryQuery.data
            ? `${summaryQuery.data.name} · ${summaryQuery.data.protocol} · draft v${currentVersion}`
            : "Loading operation metadata..."
        }
      >
        {summaryQuery.data ? (
          <div className="detail-hero">
            <div className="summary-grid">
              <div className="summary-card">
                <span>Status</span>
                <strong>{summaryQuery.data.status}</strong>
              </div>
              <div className="summary-card">
                <span>Published version</span>
                <strong>{summaryQuery.data.latest_published_version ?? "none"}</strong>
              </div>
              <div className="summary-card">
                <span>Updated</span>
                <strong>{new Date(summaryQuery.data.updated_at).toLocaleString()}</strong>
              </div>
            </div>

            {snapshot ? (
              <div className="target-grid">
                {targetRows.map(([label, value]) => (
                  <div className="target-card" key={label}>
                    <span>{label}</span>
                    <strong>{value}</strong>
                  </div>
                ))}
              </div>
            ) : null}
          </div>
        ) : null}
      </PageSection>

      {snapshot ? (
        <PageSection
          title="Target Contract"
          subtitle="The runtime transport details below are the fixed contract exposed as one MCP tool."
        >
          <div className="metadata-grid">
            <div className="result-panel">
              <h3>Tool description</h3>
              <dl className="key-value-list">
                <div>
                  <dt>Title</dt>
                  <dd>{snapshot.tool_description.title}</dd>
                </div>
                <div>
                  <dt>Tags</dt>
                  <dd>{snapshot.tool_description.tags.join(", ") || "none"}</dd>
                </div>
              </dl>
              <p className="body-copy">{snapshot.tool_description.description}</p>
            </div>
            <div className="result-panel">
              <h3>Execution config</h3>
              <pre>{JSON.stringify(snapshot.execution_config, null, 2)}</pre>
            </div>
            <div className="result-panel">
              <h3>Transport headers</h3>
              <pre>{JSON.stringify(readExecutionHeaders(snapshot.execution_config), null, 2)}</pre>
            </div>
            {snapshot.target.kind === "rest" ? (
              <div className="result-panel">
                <h3>REST static headers</h3>
                <pre>{JSON.stringify(snapshot.target.static_headers ?? {}, null, 2)}</pre>
              </div>
            ) : null}
          </div>
        </PageSection>
      ) : null}

      {snapshot?.target.kind === "grpc" ? (
        <PageSection
          title="gRPC Discovery"
          subtitle="Descriptor artifacts and discovered unary methods for the current draft version."
        >
          <GrpcDescriptorPanel operationId={operationId} version={currentVersion} />
        </PageSection>
      ) : null}

      <PageSection
        title="Samples And Draft"
        subtitle={snapshot ? draftSubtitle(snapshot.target) : "Prepare schema and mapping drafts."}
        actions={
          <button
            className="button-primary"
            onClick={() => draftMutation.mutate()}
            type="button"
          >
            {draftMutation.isPending ? "Generating..." : "Generate draft"}
          </button>
        }
      >
        <SampleUploadPanel operationId={operationId} />
        <SchemaViewerPanel
          operationRecord={versionQuery.data}
          draftResult={draftMutation.data}
        />
      </PageSection>

      <div className="detail-columns">
        <PageSection
          title="Test Run"
          subtitle="Run the current draft version through the runtime before publishing."
        >
          <TestRunPanel operationId={operationId} version={currentVersion} />
        </PageSection>

        <PageSection
          title="Publish"
          subtitle="Promote the current draft version into the active MCP tool catalog."
        >
          <PublishOperationPanel operationId={operationId} version={currentVersion} />
        </PageSection>
      </div>

      <div className="detail-columns">
        <PageSection
          title="YAML Export And Reimport"
          subtitle="Export the current version, inspect the YAML, then upsert it through the same backend contract."
          actions={
            <button
              className="button-secondary"
              type="button"
              onClick={() => exportMutation.mutate()}
            >
              {exportMutation.isPending ? "Exporting..." : "Export YAML"}
            </button>
          }
        >
          <div className="stack-layout">
            {exportedYaml ? (
              <>
                <pre className="yaml-panel">{exportedYaml}</pre>
                <div className="button-row">
                  <button
                    className="button-primary"
                    type="button"
                    onClick={() => importMutation.mutate(exportedYaml)}
                  >
                    {importMutation.isPending ? "Importing..." : "Upsert from YAML"}
                  </button>
                </div>
              </>
            ) : (
              <p className="body-copy">
                Export YAML to inspect the current operation snapshot and transport contract.
              </p>
            )}
            {importMutation.data ? (
              <div className="feedback-card feedback-success">
                Imported version {String(importMutation.data.version)} in{" "}
                {String(importMutation.data.import_mode)} mode.
              </div>
            ) : null}
          </div>
        </PageSection>

        <PageSection
          title="Auth Profiles"
          subtitle="Profiles currently available to the admin backend and execution config."
        >
          <div className="operation-grid">
            {(authProfilesQuery.data?.items ?? []).map((profile) => (
              <div className="operation-card" key={profile.id}>
                <div className="operation-card-top">
                  <span className="status-pill status-testing">{profile.kind}</span>
                </div>
                <h3>{profile.name}</h3>
                <p className="operation-name">{profile.id}</p>
                <pre>{JSON.stringify(profile.config, null, 2)}</pre>
              </div>
            ))}
          </div>
        </PageSection>
      </div>
    </div>
  );
}
