import React from "react";
import { displayDateStamp, fmtClock, fmtDate } from "./time";
import { LoadingTitle } from "./loading-indicator";
import { errorMessage, requestBlob, requestJson } from "./unidesk-error";
import { UniDeskErrorBanner } from "./unidesk-error-banner";
import { useNotification } from "./notification-context";

type AnyRecord = Record<string, any>;

const h = React.createElement;
const { useEffect } = React;
const useState: any = React.useState;

const EMPTY_FORM = {
  id: "",
  sequenceNo: "",
  contractNo: "",
  name: "",
  currentStatus: "",
  pending: "",
  paymentStatus: "",
  notes: "",
};


function StatusBadge({ status, children }: AnyRecord) {
  const normalized = String(status || "unknown").toLowerCase();
  return h("span", { className: `status-badge ${normalized}` }, children || status || "unknown");
}

function MetricCard({ label, value, hint, tone }: AnyRecord) {
  return h("article", { className: `metric-card ${tone || ""}` },
    h("div", { className: "metric-label" }, label),
    h("div", { className: "metric-value" }, value),
    h("div", { className: "metric-hint" }, hint),
  );
}

function Panel({ title, eyebrow, actions, children, className, loading }: AnyRecord) {
  return h("section", { className: `panel ${className || ""}` },
    h("div", { className: "panel-head" },
      h("div", null,
        eyebrow ? h("p", { className: "panel-eyebrow" }, eyebrow) : null,
        h(LoadingTitle, { title, loading }),
      ),
      actions ? h("div", { className: "panel-actions" }, actions) : null,
    ),
    h("div", { className: "panel-body" }, children),
  );
}

function RawButton({ title, data, onOpen, testId }: AnyRecord) {
  return h("button", {
    type: "button",
    className: "ghost-btn",
    "data-testid": testId,
    onClick: () => onOpen(title, data),
  }, "查看原始JSON");
}

function EmptyState({ title, text }: AnyRecord) {
  return h("div", { className: "empty-state" }, h("strong", null, title), h("span", null, text));
}

function microserviceRuntime(service: any): AnyRecord {
  return service?.runtime && typeof service.runtime === "object" && !Array.isArray(service.runtime) ? service.runtime : {};
}

function microserviceBackend(service: any): AnyRecord {
  return service?.backend && typeof service.backend === "object" && !Array.isArray(service.backend) ? service.backend : {};
}

function microserviceRepository(service: any): AnyRecord {
  return service?.repository && typeof service.repository === "object" && !Array.isArray(service.repository) ? service.repository : {};
}

function projectApi(apiBaseUrl: string, path: string): string {
  return `${apiBaseUrl}/microservices/project-manager/proxy${path}`;
}

function projectToForm(project: AnyRecord): AnyRecord {
  return {
    id: String(project.id || ""),
    sequenceNo: project.sequenceNo === null || project.sequenceNo === undefined ? "" : String(project.sequenceNo),
    contractNo: String(project.contractNo || ""),
    name: String(project.name || ""),
    currentStatus: String(project.currentStatus || ""),
    pending: String(project.pending || ""),
    paymentStatus: String(project.paymentStatus || ""),
    notes: String(project.notes || ""),
  };
}

function formToPayload(form: AnyRecord): AnyRecord {
  return {
    sequenceNo: form.sequenceNo === "" ? null : Number(form.sequenceNo),
    contractNo: String(form.contractNo || "").trim(),
    name: String(form.name || "").trim(),
    currentStatus: String(form.currentStatus || "").trim(),
    pending: String(form.pending || "").trim(),
    paymentStatus: String(form.paymentStatus || "").trim(),
    paymentRatio: String(form.paymentStatus || "").trim(),
    notes: String(form.notes || "").trim(),
  };
}

function safeId(value: any): string {
  return String(value || "item").replace(/[^A-Za-z0-9_-]+/g, "-");
}

function arrayBufferToBase64(buffer: ArrayBuffer): string {
  const bytes = new Uint8Array(buffer);
  let binary = "";
  const chunkSize = 0x8000;
  for (let index = 0; index < bytes.length; index += chunkSize) {
    binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
  }
  return btoa(binary);
}

function ProjectTable({ projects, activeId, onSelect, onRaw }: AnyRecord) {
  if (!projects.length) return h(EmptyState, { title: "暂无项目", text: "可以从 Excel 导入，或用右侧表单新建项目。" });
  return h("div", { className: "table-wrap project-manager-table", "data-testid": "project-manager-table" }, h("table", null,
    h("thead", null, h("tr", null,
      h("th", null, "序号"), h("th", null, "合同号"), h("th", null, "项目名称"), h("th", null, "当前状况"), h("th", null, "待完成"), h("th", null, "付款"), h("th", null, "其它"), h("th", null, "操作"),
    )),
    h("tbody", null, projects.map((project: AnyRecord) => h("tr", { key: project.id, className: activeId === project.id ? "active-row" : "", "data-testid": `project-manager-row-${safeId(project.id)}` },
      h("td", null, project.sequenceNo ?? "--"),
      h("td", null, h("strong", null, project.contractNo || "--"), h("code", null, project.id || "--")),
      h("td", null, h("strong", null, project.name || "--"), h("span", { className: "muted block" }, project.sourceFile || "--")),
      h("td", null, project.currentStatus || "--"),
      h("td", null, h("span", { className: "preline" }, project.pending || "--")),
      h("td", null, h(StatusBadge, { status: Number(project.paymentRatio || 0) >= 1 ? "online" : "warn" }, project.paymentStatus || "--")),
      h("td", null, project.notes || "--"),
      h("td", null, h("div", { className: "inline-actions" },
        h("button", { type: "button", className: "ghost-btn", onClick: () => onSelect(project), "data-testid": `project-manager-edit-${safeId(project.id)}` }, "编辑"),
        h(RawButton, { title: `Project ${project.contractNo || project.id}`, data: project, onOpen: onRaw, testId: `raw-project-${safeId(project.id)}` }),
      )),
    ))),
  ));
}

export function ProjectManagerPage({ microservices, onRaw, apiBaseUrl = "/api" }: AnyRecord) {
  const service = microservices.find((item: any) => item.id === "project-manager") || null;
  const [state, setState] = useState({ loading: false, saving: false, importing: false, exporting: false, error: "", notice: "", health: null, list: null, refreshedAt: null });
  const [form, setForm] = useState({ ...EMPTY_FORM });
  const [query, setQuery] = useState("");
  const [status, setStatus] = useState("all");
  const { addNotification } = useNotification();

  async function load(nextQuery = query, nextStatus = status): Promise<void> {
    if (!service) return;
    setState((prev: any) => ({ ...prev, loading: true, error: "" }));
    try {
      const params = new URLSearchParams({ pageSize: "200", status: nextStatus });
      if (nextQuery.trim()) params.set("q", nextQuery.trim());
      const [health, list] = await Promise.all([
        requestJson(`${apiBaseUrl}/microservices/project-manager/health`),
        requestJson(projectApi(apiBaseUrl, `/api/projects?${params.toString()}`)),
      ]);
      setState((prev: any) => ({ ...prev, loading: false, health, list, refreshedAt: new Date(), error: "" }));
    } catch (err) {
      setState((prev: any) => ({ ...prev, loading: false, error: errorMessage(err, "Project Manager 加载失败") }));
    }
  }

  useEffect(() => {
    load();
  }, [service?.id, service?.runtime?.providerStatus]);

  async function submitProject(event: any): Promise<void> {
    event.preventDefault();
    setState((prev: any) => ({ ...prev, saving: true, error: "", notice: "" }));
    try {
      const payload = formToPayload(form);
      if (form.id) {
        await requestJson(projectApi(apiBaseUrl, `/api/projects/${encodeURIComponent(form.id)}`), { method: "PUT", body: JSON.stringify(payload) });
      } else {
        await requestJson(projectApi(apiBaseUrl, "/api/projects"), { method: "POST", body: JSON.stringify(payload) });
      }
      const msg = form.id ? "项目已更新" : "项目已创建";
      setState((prev: any) => ({ ...prev, saving: false, notice: msg }));
      addNotification("success", msg);
      await load();
    } catch (err) {
      setState((prev: any) => ({ ...prev, saving: false, error: errorMessage(err, "保存项目失败") }));
    }
  }

  async function deleteCurrent(): Promise<void> {
    if (!form.id) return;
    if (!window.confirm(`删除项目 ${form.contractNo || form.name || form.id} ?`)) return;
    setState((prev: any) => ({ ...prev, saving: true, error: "", notice: "" }));
    try {
      await requestJson(projectApi(apiBaseUrl, `/api/projects/${encodeURIComponent(form.id)}`), { method: "DELETE" });
      setForm({ ...EMPTY_FORM });
      const msg = "项目已删除";
      setState((prev: any) => ({ ...prev, saving: false, notice: msg }));
      addNotification("success", msg);
      await load();
    } catch (err) {
      setState((prev: any) => ({ ...prev, saving: false, error: errorMessage(err, "删除项目失败") }));
    }
  }

  async function importExcel(event: any): Promise<void> {
    const file = event.target.files?.[0];
    if (!file) return;
    setState((prev: any) => ({ ...prev, importing: true, error: "", notice: "" }));
    try {
      const contentBase64 = arrayBufferToBase64(await file.arrayBuffer());
      const result = await requestJson(projectApi(apiBaseUrl, "/api/import/excel"), {
        method: "POST",
        body: JSON.stringify({ fileName: file.name, contentBase64, replace: false }),
      });
      const msg = `Excel 已导入 ${result.imported || 0} 条项目`;
      setState((prev: any) => ({ ...prev, importing: false, notice: msg }));
      addNotification("success", msg);
      event.target.value = "";
      await load();
    } catch (err) {
      setState((prev: any) => ({ ...prev, importing: false, error: errorMessage(err, "Excel 导入失败") }));
    }
  }

  async function exportExcel(): Promise<void> {
    setState((prev: any) => ({ ...prev, exporting: true, error: "" }));
    try {
      const blob = await requestBlob(projectApi(apiBaseUrl, "/api/projects/export.xlsx"));
      const href = URL.createObjectURL(blob);
      const anchor = document.createElement("a");
      anchor.href = href;
      anchor.download = `project-manager-${displayDateStamp()}.xlsx`;
      document.body.appendChild(anchor);
      anchor.click();
      anchor.remove();
      URL.revokeObjectURL(href);
      setState((prev: any) => ({ ...prev, exporting: false, notice: "Excel 已导出" }));
    } catch (err) {
      setState((prev: any) => ({ ...prev, exporting: false, error: errorMessage(err, "Excel 导出失败") }));
    }
  }

  if (!service) return h(EmptyState, { title: "Project Manager 未登记", text: "请在 config.json 的 microservices 中登记用户服务 id=project-manager" });

  const runtime = microserviceRuntime(service);
  const repository = microserviceRepository(service);
  const backend = microserviceBackend(service);
  const projects = Array.isArray(state.list?.projects) ? state.list.projects : [];
  const summary = state.list?.summary || {};
  const health = state.health || {};

  return h("div", { className: "project-manager-page", "data-testid": "project-manager-page" },
    h(Panel, {
      title: "项目管理工作台",
      eyebrow: "Main Server PostgreSQL 用户服务",
      loading: state.loading || state.exporting,
      actions: h("div", { className: "panel-actions" },
        h("button", { type: "button", className: "ghost-btn", disabled: state.loading, onClick: () => load(), "data-testid": "project-manager-refresh-button" }, state.loading ? "刷新中" : "刷新"),
        h("button", { type: "button", className: "ghost-btn", disabled: state.exporting, onClick: exportExcel, "data-testid": "project-manager-export-button" }, state.exporting ? "导出中" : "导出 Excel"),
        h(RawButton, { title: "Project Manager 用户服务", data: service, onOpen: onRaw, testId: "raw-project-manager-service" }),
      ),
    },
      h("div", { className: "project-manager-hero" },
        h(MetricCard, { label: "项目总数", value: summary.total ?? projects.length, hint: `PG 表 ${health.storage?.table || "project_manager_projects"}`, tone: "ok" }),
        h(MetricCard, { label: "进行中", value: summary.active ?? "--", hint: "当前状态未完全完成" }),
        h(MetricCard, { label: "已完成", value: summary.completed ?? "--", hint: "按 完成 关键字统计", tone: "ok" }),
        h(MetricCard, { label: "未全款", value: summary.unpaid ?? "--", hint: "付款比例 < 1", tone: Number(summary.unpaid || 0) > 0 ? "warn" : "ok" }),
      ),
      h(UniDeskErrorBanner, { error: state.error }),
      state.notice ? h("div", { className: "form-success" }, state.notice) : null,
    ),
    h("div", { className: "project-manager-hero" },
      h("div", { className: "microservice-ref-card" }, h("span", null, "Repo"), h("strong", null, repository.url || "--"), h("code", null, repository.commitId || "--")),
      h("div", { className: "microservice-ref-card" }, h("span", null, "Main Server Docker"), h("strong", null, `${backend.nodeBindHost || "--"}:${backend.nodePort || "--"}`), h("code", null, `${repository.composeService || "--"} / ${repository.containerName || "--"}`)),
      h("div", { className: "microservice-ref-card" }, h("span", null, "Runtime"), h("strong", null, runtime.providerName || service.providerId), h("code", null, `Health ${health.ok ? "OK" : "--"} / ${state.refreshedAt ? fmtClock(state.refreshedAt) : "--"}`)),
      h("div", { className: "microservice-ref-card" }, h("span", null, "Import Source"), h("strong", null, "D601 WeChat Excel"), h("code", null, "合作项目列表_I_20260309.xlsx")),
    ),
    h("div", { className: "project-manager-layout" },
      h(Panel, {
        title: "项目清单",
        eyebrow: "CRUD + Excel Export",
        loading: state.loading || state.importing || state.exporting,
        actions: h("div", { className: "inline-actions project-manager-filters" },
          h("input", { value: query, onChange: (event: any) => setQuery(event.target.value), placeholder: "搜索合同号 / 项目名称 / 状态", "data-testid": "project-manager-search" }),
          h("select", { value: status, onChange: (event: any) => { setStatus(event.target.value); load(query, event.target.value); }, "data-testid": "project-manager-status-filter" },
            h("option", { value: "all" }, "全部"),
            h("option", { value: "active" }, "进行中"),
            h("option", { value: "completed" }, "已完成"),
            h("option", { value: "unpaid" }, "未全款"),
          ),
          h("button", { type: "button", className: "ghost-btn", onClick: () => load(query, status) }, "筛选"),
        ),
      }, h(ProjectTable, { projects, activeId: form.id, onSelect: (project: AnyRecord) => setForm(projectToForm(project)), onRaw })),
      h(Panel, { title: form.id ? "编辑项目" : "新建项目", eyebrow: "PostgreSQL Write Path", loading: state.saving || state.importing },
        h("form", { className: "stack-form project-manager-form", onSubmit: submitProject, "data-testid": "project-manager-form" },
          form.id ? h("label", null, "项目 ID", h("input", { value: form.id, disabled: true })) : null,
          h("label", null, "序号", h("input", { type: "number", value: form.sequenceNo, onChange: (event: any) => setForm((prev: any) => ({ ...prev, sequenceNo: event.target.value })) })),
          h("label", null, "合同号", h("input", { value: form.contractNo, onChange: (event: any) => setForm((prev: any) => ({ ...prev, contractNo: event.target.value })), required: true })),
          h("label", null, "项目名称", h("input", { value: form.name, onChange: (event: any) => setForm((prev: any) => ({ ...prev, name: event.target.value })), required: true })),
          h("label", null, "当前状况", h("textarea", { value: form.currentStatus, onChange: (event: any) => setForm((prev: any) => ({ ...prev, currentStatus: event.target.value })) })),
          h("label", null, "待完成", h("textarea", { value: form.pending, onChange: (event: any) => setForm((prev: any) => ({ ...prev, pending: event.target.value })) })),
          h("label", null, "付款情况", h("input", { value: form.paymentStatus, onChange: (event: any) => setForm((prev: any) => ({ ...prev, paymentStatus: event.target.value })), placeholder: "例如 1 / 0.5 / 50%" })),
          h("label", null, "其它", h("input", { value: form.notes, onChange: (event: any) => setForm((prev: any) => ({ ...prev, notes: event.target.value })) })),
          h("div", { className: "inline-actions" },
            h("button", { type: "submit", className: "primary-btn", disabled: state.saving, "data-testid": "project-manager-save-button" }, state.saving ? "保存中" : form.id ? "保存修改" : "创建项目"),
            h("button", { type: "button", className: "ghost-btn", onClick: () => setForm({ ...EMPTY_FORM }) }, "清空"),
            form.id ? h("button", { type: "button", className: "danger-btn", disabled: state.saving, onClick: deleteCurrent, "data-testid": "project-manager-delete-button" }, "删除") : null,
          ),
        ),
        h("div", { className: "project-manager-import" },
          h("p", { className: "muted paragraph" }, "浏览器只访问 UniDesk frontend；后端通过同源用户服务代理写入主 PostgreSQL，不暴露 4233 公网端口。"),
          h("label", { className: "file-import" }, state.importing ? "导入中..." : "导入 Excel", h("input", { type: "file", accept: ".xlsx", onChange: importExcel, disabled: state.importing, "data-testid": "project-manager-import-input" })),
        ),
      ),
    ),
  );
}
