import { useEffect, useMemo, useState } from "react";
import { Spin } from "antd";
import {
  Card,
  Switch,
  Empty,
  Button,
  Modal,
  Form,
  Input,
  InputNumber,
  Select,
} from "@agentscope-ai/design";
import api from "../../../api";
import {
  EyeInvisibleOutlined,
  ThunderboltOutlined,
  ClockCircleOutlined,
  SettingOutlined,
} from "@ant-design/icons";
import { useTools } from "./useTools";
import { useTranslation } from "react-i18next";
import type { ToolInfo } from "../../../api/modules/tools";
import { PageHeader } from "@/components/PageHeader";
import styles from "./index.module.less";

/** Stable background colours for the initial-letter fallback icon. */
const ICON_PALETTE = [
  "#f56a00",
  "#7265e6",
  "#ffbf00",
  "#00a2ae",
  "#87d068",
  "#1890ff",
  "#eb2f96",
  "#722ed1",
];

function hashStringToIndex(value: string, mod: number): number {
  let hash = 0;
  for (let i = 0; i < value.length; i++) {
    hash = (hash * 31 + value.charCodeAt(i)) | 0;
  }
  return Math.abs(hash) % mod;
}

/** Renders the emoji icon or a coloured initial-letter badge as fallback. */
function ToolIcon({ icon, name }: { icon: string; name: string }) {
  if (icon) {
    return <span>{icon}</span>;
  }
  const letter = name.charAt(0).toUpperCase();
  const backgroundColor =
    ICON_PALETTE[hashStringToIndex(name, ICON_PALETTE.length)];
  return (
    <span className={styles.toolIconFallback} style={{ backgroundColor }}>
      {letter}
    </span>
  );
}

/** Configuration modal for tools that require configuration */
function ToolConfigModal({
  tool,
  visible,
  onClose,
  onSave,
}: {
  tool: ToolInfo;
  visible: boolean;
  onClose: () => void;
  onSave: (values: Record<string, any>) => Promise<void>;
}) {
  const [form] = Form.useForm();
  const [saving, setSaving] = useState(false);
  const [loadingConfig, setLoadingConfig] = useState(false);
  const { t } = useTranslation();

  // Fetch latest config from backend whenever the modal opens.
  // Cleanup cancels stale in-flight requests on rapid tool switches.
  useEffect(() => {
    if (!visible || !tool) return;
    form.resetFields();
    setLoadingConfig(true);
    let cancelled = false;
    api
      .getToolConfig(tool.name)
      .then((config) => {
        if (!cancelled) form.setFieldsValue(config || {});
      })
      .catch(() => {
        // Leave form empty on error
      })
      .finally(() => {
        if (!cancelled) setLoadingConfig(false);
      });
    return () => {
      cancelled = true;
    };
  }, [visible, tool.name, form]);

  const handleSave = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);
      await onSave(values);
      // Success message is shown in useTools.saveToolConfig
      onClose();
    } catch (error) {
      console.error("Failed to save config:", error);
      // Error is already handled and shown in useTools
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal
      title={`${t("tools.configure")} - ${tool.name}`}
      open={visible}
      onCancel={onClose}
      onOk={handleSave}
      confirmLoading={saving || loadingConfig}
      okButtonProps={{ disabled: loadingConfig }}
      okText={t("common.save")}
      cancelText={t("common.cancel")}
    >
      <Spin spinning={loadingConfig}>
        <Form form={form} layout="vertical">
          {tool.config_fields?.map((field) => {
            // Render different input types based on field type
            const renderInput = () => {
              switch (field.type) {
                case "password":
                  return (
                    <Input.Password
                      placeholder={field.placeholder}
                      autoComplete="off"
                    />
                  );

                case "number":
                  return (
                    <InputNumber
                      placeholder={field.placeholder}
                      min={field.min}
                      max={field.max}
                      style={{ width: "100%" }}
                    />
                  );

                case "boolean":
                  return <Switch />;

                case "select":
                  return (
                    <Select placeholder={field.placeholder}>
                      {field.options?.map((option) => (
                        <Select.Option key={option} value={option}>
                          {option}
                        </Select.Option>
                      ))}
                    </Select>
                  );

                case "textarea":
                  return (
                    <Input.TextArea
                      placeholder={field.placeholder}
                      rows={4}
                      autoSize={{ minRows: 2, maxRows: 8 }}
                    />
                  );

                case "text":
                default:
                  return <Input placeholder={field.placeholder} />;
              }
            };

            return (
              <Form.Item
                key={field.name}
                name={field.name}
                label={field.label}
                rules={[
                  {
                    required: field.required,
                    message: `${field.label} is required`,
                  },
                ]}
                help={field.help}
                valuePropName={field.type === "boolean" ? "checked" : "value"}
              >
                {renderInput()}
              </Form.Item>
            );
          })}
        </Form>
      </Spin>
    </Modal>
  );
}

export default function ToolsPage() {
  const { t } = useTranslation();
  const {
    tools,
    loading,
    batchLoading,
    toggleEnabled,
    toggleAsyncExecution,
    enableAll,
    disableAll,
    loadTools,
    saveToolConfig,
  } = useTools();
  const [configModalVisible, setConfigModalVisible] = useState(false);
  const [currentTool, setCurrentTool] = useState<ToolInfo | null>(null);

  const handleConfigure = (tool: ToolInfo) => {
    setCurrentTool(tool);
    setConfigModalVisible(true);
  };

  const handleSaveConfig = async (values: Record<string, any>) => {
    if (!currentTool) return;
    await saveToolConfig(currentTool.name, values);
    await loadTools();
  };

  const { enabledTools, disabledTools } = useMemo(() => {
    const enabled = tools.filter((tool) => tool.enabled);
    const disabled = tools.filter((tool) => !tool.enabled);
    return { enabledTools: enabled, disabledTools: disabled };
  }, [tools]);

  const isToolConfigured = (tool: ToolInfo) =>
    !tool.requires_config ||
    (tool.config_values && Object.keys(tool.config_values).length > 0);

  const handleAvailableItemClick = (tool: ToolInfo) => {
    if (tool.requires_config && !isToolConfigured(tool)) {
      handleConfigure(tool);
    } else {
      toggleEnabled(tool);
    }
  };

  return (
    <div className={styles.toolsPage}>
      <PageHeader
        items={[{ title: t("nav.agent") }, { title: t("tools.title") }]}
        extra={
          <div className={styles.headerAction}>
            <Switch
              checked={enabledTools.length > 0 && disabledTools.length === 0}
              onChange={() =>
                disabledTools.length > 0 ? enableAll() : disableAll()
              }
              disabled={batchLoading || loading}
              checkedChildren={t("tools.enableAll")}
              unCheckedChildren={t("tools.disableAll")}
            />
          </div>
        }
      />
      <div className={styles.toolsContainer}>
        {loading ? (
          <div className={styles.loading}>
            <p>{t("common.loading")}</p>
          </div>
        ) : tools.length === 0 ? (
          <Empty description={t("tools.emptyState")} />
        ) : (
          <>
            {/* Enabled Section */}
            <div className={styles.panelSection}>
              <div className={styles.panelTitle}>
                <span className={styles.panelDotGreen} />
                {t("common.enabled")}
                <span className={styles.panelCount}>
                  {enabledTools.length} {t("tools.active")}
                </span>
              </div>

              {enabledTools.length > 0 ? (
                <div className={styles.toolsGrid}>
                  {enabledTools.map((tool) => (
                    <Card
                      key={tool.name}
                      className={`${styles.toolCard} ${styles.enabledCard}`}
                    >
                      <div className={styles.cardHeader}>
                        <h3 className={styles.toolName} title={tool.name}>
                          <ToolIcon icon={tool.icon} name={tool.name} />{" "}
                          <span className={styles.toolNameText}>
                            {tool.name}
                          </span>
                        </h3>
                        <div className={styles.statusContainer}>
                          <span className={styles.statusDot} />
                          <span className={styles.statusText}>
                            {t("common.enabled")}
                          </span>
                        </div>
                      </div>

                      <p className={styles.toolDescription}>
                        {tool.description}
                      </p>

                      {/* Show config status */}
                      {tool.requires_config && (
                        <div className={styles.configStatus}>
                          {tool.config_values &&
                          Object.keys(tool.config_values).length > 0 ? (
                            <span className={styles.configured}>
                              ✓ {t("tools.configured")}
                            </span>
                          ) : (
                            <span className={styles.notConfigured}>
                              ⚠ {t("tools.requiresConfig")}
                            </span>
                          )}
                        </div>
                      )}

                      <div className={styles.cardFooter}>
                        {[
                          "execute_shell_command",
                          "delegate_external_agent",
                        ].includes(tool.name) && (
                          <Button
                            className={styles.toggleButton}
                            onClick={() => toggleAsyncExecution(tool)}
                            disabled={!tool.enabled}
                            icon={
                              tool.async_execution ? (
                                <ThunderboltOutlined />
                              ) : (
                                <ClockCircleOutlined />
                              )
                            }
                          >
                            {tool.async_execution
                              ? t("tools.asyncExecutionEnabled")
                              : t("tools.asyncExecutionDisabled")}
                          </Button>
                        )}
                        {/* Add configure button */}
                        {tool.requires_config && (
                          <Button
                            className={styles.toggleButton}
                            onClick={() => handleConfigure(tool)}
                            icon={<SettingOutlined />}
                          >
                            {t("tools.configure")}
                          </Button>
                        )}
                        <Button
                          className={styles.toggleButton}
                          onClick={() => toggleEnabled(tool)}
                          icon={<EyeInvisibleOutlined />}
                        >
                          {t("common.disable")}
                        </Button>
                      </div>
                    </Card>
                  ))}
                </div>
              ) : (
                <div className={styles.emptyEnabled}>
                  <p>{t("tools.noEnabled")}</p>
                  <Button
                    type="primary"
                    onClick={() => {
                      document
                        .getElementById("available-tools")
                        ?.scrollIntoView({ behavior: "smooth" });
                    }}
                  >
                    {t("tools.goEnableBtn")}
                  </Button>
                </div>
              )}
            </div>

            {/* Available Section */}
            {disabledTools.length > 0 && (
              <div id="available-tools" className={styles.panelSectionDashed}>
                <div className={styles.panelTitle}>
                  <span className={styles.panelDotGray} />
                  {t("tools.available")}
                </div>
                <div className={styles.availableGrid}>
                  {disabledTools.map((tool) => (
                    <div
                      key={tool.name}
                      className={styles.availableItem}
                      onClick={() => handleAvailableItemClick(tool)}
                    >
                      <ToolIcon icon={tool.icon} name={tool.name} />
                      <span
                        className={styles.availableItemName}
                        title={tool.name}
                      >
                        {tool.name}
                      </span>
                      <span className={styles.availableItemAction}>
                        {tool.requires_config && !isToolConfigured(tool)
                          ? t("tools.configureAction")
                          : t("tools.enableAction")}
                      </span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </>
        )}
      </div>

      {/* Config modal — key forces remount when switching tools */}
      {currentTool && (
        <ToolConfigModal
          key={currentTool.name}
          tool={currentTool}
          visible={configModalVisible}
          onClose={() => setConfigModalVisible(false)}
          onSave={handleSaveConfig}
        />
      )}
    </div>
  );
}
