"use client";

import { useState, useCallback, useMemo } from "react";
import {
  Modal,
  Steps,
  Button,
  Space,
  Checkbox,
  Table,
  Select,
  Row,
  Col,
  Flex,
  Progress,
  Typography,
  Empty,
  theme,
} from "antd";
import { ReloadOutlined } from "@ant-design/icons";
import type { BaseVersion, Config, UploadReleaseType } from "@/types";
import type { ParsedProject } from "@/services/project";
import { platforms } from "@/services/publish.schemas";
import { Template } from "@/lib/utils/template";
import type { McVersionEntry } from "@/lib/utils/mcVersion";

const { Text } = Typography;

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface PublishVersion {
  key: string;
  mc_version: string;
  artifact: string | null;
  sources: string | null;
  modrinthVersion: string;
  modrinthVersionName: string;
  existsModrinth: boolean;
  existsCurseforge: boolean;
}

interface PublishModalProps {
  open: boolean;
  config: Config;
  project: ParsedProject;
  versionRanges: McVersionEntry[] | null;
  onClose: () => void;
}

type ReleaseType = Extract<BaseVersion["version_type"], UploadReleaseType>;

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

const RELEASE_TYPE_LABEL_MAP: Record<ReleaseType, string> = {
  release: "Release",
  beta: "Beta",
  alpha: "Alpha"
};
const RELEASE_TYPES = Object.entries(RELEASE_TYPE_LABEL_MAP).map(v => ({ value: v[0], label: v[1] }));

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export function PublishModal({
  open,
  config,
  project,
  versionRanges,
  onClose,
}: PublishModalProps) {
  const { token } = theme.useToken();
  const [currentStep, setCurrentStep] = useState(0);

  // Version selection
  const [selectedVersions, setSelectedVersions] = useState<Set<string>>(
    new Set(),
  );

  // Publish settings
  const [changelog, setChangelog] = useState("");
  const [versionType, setVersionType] = useState<ReleaseType>(
    "release",
  );

  // Progress & result
  const [publishing, setPublishing] = useState(false);
  const [publishDone, setPublishDone] = useState(false);
  const [progress, setProgress] = useState<
    Record<typeof platforms[number], { done: number; total: number }>
  >({
    modrinth: { done: 0, total: 0 },
    curseforge: { done: 0, total: 0 },
  });
  const [publishResult, setPublishResult] = useState<{
    success: number;
    failed: number;
  } | null>(null);

  // Platform existing versions — loaded when modal opens
  const [loadingExisting, setLoadingExisting] = useState(false);
  const [existingModrinth, setExistingModrinth] = useState<string[]>([]);
  const [existingCurseforge, setExistingCurseforge] = useState<string[]>([]);

  const loadExisting = useCallback(async () => {
    setLoadingExisting(true);
    try {
      // TODO: Fetch existing versions from both platforms via tRPC/Server Action
      // For now, placeholder
      setExistingModrinth([]);
      setExistingCurseforge([]);
    } catch {
      // ignore
    } finally {
      setLoadingExisting(false);
    }
  }, []);

  // Pre-compute version display values
  const versionTmpl = useMemo(() => new Template(config.modrinth.version), [config.modrinth.version]);
  const versionNameTmpl = useMemo(() => new Template(config.modrinth.version_name), [config.modrinth.version_name]);

  const rangeMap = useMemo(() => {
    const map = new Map<string, string>();
    if (versionRanges) {
      for (const entry of versionRanges) {
        map.set(entry.version, entry.wildcard);
      }
    }
    return map;
  }, [versionRanges]);

  // Build publish version rows from project artifacts
  const publishVersions: PublishVersion[] = useMemo(() =>
    project.artifacts.map((a) => {
      const tmplValues = {
        version: project.version,
        mc_version: a.mc_version,
        mc_version_range: rangeMap.get(a.mc_version) ?? a.mc_version,
      };
      return {
        key: a.mc_version,
        mc_version: a.mc_version,
        artifact: a.artifact,
        sources: a.sources,
        modrinthVersion: versionTmpl.format(tmplValues),
        modrinthVersionName: versionNameTmpl.format(tmplValues),
        existsModrinth: existingModrinth.includes(a.mc_version),
        existsCurseforge: existingCurseforge.includes(a.mc_version),
      };
    }),
    [project, versionTmpl, versionNameTmpl, rangeMap, existingModrinth, existingCurseforge],
  );

  // --------------- Steps handling ---------------

  const handleNext = useCallback(() => {
    if (currentStep === 0) {
      // Init selection with all non-existing entries
      const preselected = new Set<string>();
      for (const v of publishVersions) {
        if (!v.existsModrinth || !v.existsCurseforge) {
          preselected.add(v.key);
        }
      }
      setSelectedVersions(preselected);
    }
    setCurrentStep((prev) => Math.min(prev + 1, 2));
  }, [currentStep, publishVersions]);

  const handlePrev = useCallback(() => {
    setCurrentStep((prev) => Math.max(prev - 1, 0));
  }, []);

  const handleConfirmPublish = useCallback(async () => {
    setPublishing(true);
    setPublishDone(false);
    setPublishResult(null);
    setCurrentStep(2);
    // TODO: Call tRPC mutation to publish, update progress & result
    setPublishResult({ success: 0, failed: 0 });
    setPublishDone(true);
    setPublishing(false);
  }, []);

  const handleClose = useCallback(() => {
    if (publishing) return;
    setCurrentStep(0);
    setSelectedVersions(new Set());
    setChangelog("");
    setVersionType("release");
    setPublishResult(null);
    setPublishDone(false);
    onClose();
  }, [publishing, onClose]);

  // --------------- Render: Step 1 — Version Selection ---------------

  const renderStep1 = () => {
    const modrinthColumns = [
      {
        title: "版本号",
        dataIndex: "modrinthVersion",
        key: "modrinthVersion",
      },
      {
        title: "版本名称",
        dataIndex: "modrinthVersionName",
        key: "modrinthVersionName",
      },
      {
        title: "",
        key: "select",
        width: 50,
        render: (_: unknown, record: PublishVersion) => (
          <Checkbox
            disabled={record.existsModrinth}
            checked={
              record.existsModrinth || selectedVersions.has(record.key)
            }
            onChange={(e) => {
              const next = new Set(selectedVersions);
              if (e.target.checked) next.add(record.key);
              else next.delete(record.key);
              setSelectedVersions(next);
            }}
          />
        ),
      },
    ];

    const curseforgeColumns = [
      {
        title: "MC 版本",
        dataIndex: "mc_version",
        key: "mc_version",
        width: 100,
      },
      {
        title: "显示名称",
        dataIndex: "artifact",
        key: "artifact",
        ellipsis: true,
      },
      {
        title: "",
        key: "select",
        width: 50,
        render: (_: unknown, record: PublishVersion) => (
          <Checkbox
            disabled={record.existsCurseforge}
            checked={
              record.existsCurseforge || selectedVersions.has(record.key)
            }
            onChange={(e) => {
              const next = new Set(selectedVersions);
              if (e.target.checked) next.add(record.key);
              else next.delete(record.key);
              setSelectedVersions(next);
            }}
          />
        ),
      },
    ];

    return (
      <div>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            marginBottom: token.margin,
          }}
        >
          <Text strong>选择要发布的版本</Text>
          <Button
            icon={<ReloadOutlined />}
            loading={loadingExisting}
            onClick={loadExisting}
            size="small"
          >
            刷新已有版本
          </Button>
        </div>

        {loadingExisting ? (
          <div style={{ textAlign: "center", padding: 40 }}>加载中…</div>
        ) : (
          <Row gutter={token.margin}>
            <Col span={12}>
              <Text strong style={{ display: "block", marginBottom: token.marginXS }}>
                Modrinth
              </Text>
              {publishVersions.length > 0 ? (
                <Table
                  dataSource={publishVersions}
                  columns={modrinthColumns}
                  pagination={false}
                  size="small"
                  bordered
                />
              ) : (
                <Empty description="无版本" />
              )}
            </Col>
            <Col span={12}>
              <Text strong style={{ display: "block", marginBottom: token.marginXS }}>
                CurseForge
              </Text>
              {publishVersions.length > 0 ? (
                <Table
                  dataSource={publishVersions}
                  columns={curseforgeColumns}
                  pagination={false}
                  size="small"
                  bordered
                />
              ) : (
                <Empty description="无版本" />
              )}
            </Col>
          </Row>
        )}
      </div>
    );
  };

  // --------------- Render: Step 2 — Publish Settings ---------------

  const renderStep2 = () => {
    return (
      <div>
        {/* Changelog */}
        <div style={{ marginBottom: token.marginLG }}>
          <Text strong style={{ display: "block", marginBottom: token.marginSM }}>
            Changelog (Markdown)
          </Text>
          {/* TODO: Replace with @uiw/react-md-editor */}
          <textarea
            style={{
              width: "100%",
              minHeight: 160,
              border: `1px solid ${token.colorBorder}`,
              borderRadius: token.borderRadius,
              padding: token.paddingSM,
              fontFamily: token.fontFamilyCode ?? "monospace",
              fontSize: token.fontSizeSM,
            }}
            placeholder="输入 Markdown 格式的更新日志…"
            value={changelog}
            onChange={(e) => setChangelog(e.target.value)}
          />
        </div>

        {/* Version type */}
        <div>
          <Text strong style={{ display: "block", marginBottom: token.marginSM }}>
            版本类型
          </Text>
          <Select
            value={versionType}
            onChange={(v) => setVersionType(v)}
            style={{ width: 160 }}
            options={RELEASE_TYPES}
          />
        </div>
      </div>
    );
  };

  // --------------- Render: Step 3 — Progress & Result ---------------

  const renderStep3 = () => {
    const hasModrinth = publishVersions.some(
      (v) =>
        !v.existsModrinth &&
        (selectedVersions.has(v.key) || v.existsModrinth),
    );
    const hasCurseforge = publishVersions.some(
      (v) =>
        !v.existsCurseforge &&
        (selectedVersions.has(v.key) || v.existsCurseforge),
    );

    return (
      <div>
        {/* Progress bars */}
        <div style={{ marginBottom: token.marginLG }}>
          <Flex vertical gap={token.marginSM}>
            {hasModrinth && (
              <Flex align="center" gap={token.marginXS}>
                <img
                  src="/platform/modrinth.svg"
                  alt="Modrinth"
                  style={{ width: 30, height: 30, flexShrink: 0 }}
                />
                <Text style={{ width: 80, flexShrink: 0, fontFamily: "Inter", fontWeight: "bold" }}>Modrinth</Text>
                <Progress
                  percent={Math.round(
                    (progress.modrinth.done /
                      Math.max(progress.modrinth.total, 1)) *
                      100,
                  )}
                  format={() =>
                    `${progress.modrinth.done} / ${progress.modrinth.total}`
                  }
                  style={{ flex: 1 }}
                />
              </Flex>
            )}
            {hasCurseforge && (
              <Flex align="center" gap={token.marginXS}>
                <img
                  src="/platform/curseforge.svg"
                  alt="CurseForge"
                  style={{ width: 30, height: 30, flexShrink: 0 }}
                />
                <Text style={{ width: 80, flexShrink: 0, fontFamily: "Inter", fontWeight: "bold" }}>CurseForge</Text>
                <Progress
                  percent={Math.round(
                    (progress.curseforge.done /
                      Math.max(progress.curseforge.total, 1)) *
                      100,
                  )}
                  format={() =>
                    `${progress.curseforge.done} / ${progress.curseforge.total}`
                  }
                  style={{ flex: 1 }}
                />
              </Flex>
            )}
          </Flex>
        </div>

        {/* Result */}
        {publishDone && publishResult && (
          <div
            style={{
              background: token.colorSuccessBg,
              border: `1px solid ${token.colorSuccessBorder}`,
              borderRadius: token.borderRadius,
              padding: token.padding,
            }}
          >
            <Text strong>发布结果</Text>
            <div style={{ marginTop: token.marginSM }}>
              <Text>
                成功 {publishResult.success} 个，失败 {publishResult.failed} 个
              </Text>
            </div>
          </div>
        )}
      </div>
    );
  };

  // --------------- Render ---------------

  return (
    <Modal
      title="一键发布"
      open={open}
      onCancel={handleClose}
      width={760}
      destroyOnHidden
      footer={
        publishing ? null : (
          <Space>
            {currentStep > 0 && currentStep < 2 && (
              <Button onClick={handlePrev}>上一步</Button>
            )}
            {currentStep === 0 ? (
              <Button type="primary" onClick={handleNext}>
                下一步
              </Button>
            ) : currentStep === 1 ? (
              <Button type="primary" onClick={handleConfirmPublish}>
                确认发布
              </Button>
            ) : (
              <Button type="primary" onClick={handleClose}>
                关闭
              </Button>
            )}
          </Space>
        )
      }
    >
      <Steps
        current={currentStep}
        size="small"
        style={{ marginBottom: 24 }}
        items={[
          { title: "版本选择" },
          { title: "发布设置" },
          { title: "发布进度" },
        ]}
      />

      {currentStep === 0
        ? renderStep1()
        : currentStep === 1
          ? renderStep2()
          : renderStep3()}
    </Modal>
  );
}
