import { useMemo, useRef, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import { Alert, Button, Card, ConfigProvider, InputNumber, Table, Tag } from "antd";
import zhCN from "antd/locale/zh_CN";

type Conclusion = "Ok" | "IncreaseMeasurementsToSix" | "RecalibrateInstrument";

type CalibrationParams = {
  factor: number;
  expanded_uncertainty_percent: number;
  coverage_factor: number;
};

type NuclideMeasurements = {
  measured_values: number[];
  calibration: CalibrationParams;
};

type AcceptanceLimits = {
  ira_limit: number;
  ir_limit: number;
};

type SampleInput = {
  ra: NuclideMeasurements;
  th: NuclideMeasurements;
  k: NuclideMeasurements;
  limits: AcceptanceLimits;
};

type McmIndexStats = {
  mean: number;
  std_dev: number;
  p2_5: number;
  p97_5: number;
  standard_value: number;
  pass_probability: number;
  fail_probability: number;
};

type McmResult = {
  iterations: number;
  ira: McmIndexStats;
  ir: McmIndexStats;
  overall_pass_probability: number;
  overall_fail_probability: number;
};

type NuclideResult = {
  mean_measured: number;
  mean_calibrated: number;
  type_a_uncertainty: number;
  type_b_relative: number;
  type_b_uncertainty: number;
  sensitivity_coefficient: number;
  combined_uncertainty: number;
};

type IndexResult = {
  value: number;
  standard_uncertainty: number;
  relative_uncertainty_percent: number;
};

type CalculationResult = {
  measurement_count: number;
  ra: NuclideResult;
  th: NuclideResult;
  k: NuclideResult;
  ira: IndexResult;
  ir: IndexResult;
  conclusion: Conclusion;
  mcm: McmResult;
};

type MeasurementRow = {
  key: number;
  ra: number | null;
  th: number | null;
  k: number | null;
};

type ResultRow = { name: string } & NuclideResult;

type McmRow = { name: string } & McmIndexStats;

type CalibrationRow = { key: string; name: string } & CalibrationParams;

type FocusableInput = {
  focus: () => void;
};

const defaultCalibration = {
  ra: { factor: 0.916, expanded_uncertainty_percent: 6.3, coverage_factor: 2 },
  th: { factor: 0.884, expanded_uncertainty_percent: 6.9, coverage_factor: 2 },
  k: { factor: 0.961, expanded_uncertainty_percent: 6.7, coverage_factor: 2 }
};

const defaultLimits: AcceptanceLimits = { ira_limit: 1.0, ir_limit: 1.0 };

const initialRows: MeasurementRow[] = [
  { key: 1, ra: 100, th: 110, k: 560 },
  { key: 2, ra: 102, th: 111, k: 565 },
  { key: 3, ra: 98, th: 109, k: 555 },
  { key: 4, ra: 101, th: 110, k: 562 },
  { key: 5, ra: 99, th: 112, k: 558 },
  { key: 6, ra: 100, th: 108, k: 561 }
];

const conclusionText: Record<Conclusion, string> = {
  Ok: "OK",
  IncreaseMeasurementsToSix: "请增加试验次数至 6 次",
  RecalibrateInstrument: "校准仪器后重新测量"
};

function formatNumber(value: number, digits = 4) {
  if (!Number.isFinite(value)) return "-";
  return value.toFixed(digits);
}

function formatPercent(value: number, digits = 2) {
  if (!Number.isFinite(value)) return "-";
  return (value * 100).toFixed(digits) + "%";
}

function App() {
  const [rows, setRows] = useState<MeasurementRow[]>(initialRows);
  const [limits, setLimits] = useState<AcceptanceLimits>(defaultLimits);
  const [result, setResult] = useState<CalculationResult | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const firstCellRefs = useRef<Record<number, FocusableInput | null>>({});

  const dataSource = useMemo(() => rows, [rows]);

  const updateRow = (key: number, field: keyof Omit<MeasurementRow, "key">, value: number | null) => {
    setRows((current) =>
      current.map((row) => (row.key === key ? { ...row, [field]: value } : row))
    );
  };

  const addRow = () => {
    const key = Date.now();
    setRows((current) => [...current, { key, ra: null, th: null, k: null }]);
    window.setTimeout(() => firstCellRefs.current[key]?.focus(), 0);
  };

  const removeRow = (key: number) => {
    setRows((current) => current.filter((row) => row.key !== key));
  };

  const buildInput = (): SampleInput => {
    const toValues = (field: keyof Omit<MeasurementRow, "key">) =>
      rows.map((row) => row[field]).filter((value): value is number => typeof value === "number");

    return {
      ra: { measured_values: toValues("ra"), calibration: defaultCalibration.ra },
      th: { measured_values: toValues("th"), calibration: defaultCalibration.th },
      k: { measured_values: toValues("k"), calibration: defaultCalibration.k },
      limits
    };
  };

  const calculate = async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await invoke<CalculationResult>("calculate", { input: buildInput() });
      setResult(response);
    } catch (err) {
      setResult(null);
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  };

  return (
    <ConfigProvider locale={zhCN}>
      <main className="app-shell">
        <section className="workspace">
          <div className="content-grid">
            <Card
              title="重复测量值"
              className="panel measurements-panel"
            >
              <div className="measurement-table">
                <Table<MeasurementRow>
                  pagination={false}
                  dataSource={dataSource}
                  rowKey="key"
                  size="small"
                  columns={[
                    {
                      title: "序号",
                      key: "index",
                      width: 56,
                      align: "center",
                      render: (_, _row, index) => index + 1
                    },
                    {
                      title: "Ra-226",
                      dataIndex: "ra",
                      render: (_, row) => (
                        <InputNumber
                          ref={(instance) => {
                            firstCellRefs.current[row.key] = instance;
                          }}
                          value={row.ra}
                          min={0}
                          onChange={(value) => updateRow(row.key, "ra", value)}
                        />
                      )
                    },
                    {
                      title: "Th-232",
                      dataIndex: "th",
                      render: (_, row) => (
                        <InputNumber value={row.th} min={0} onChange={(value) => updateRow(row.key, "th", value)} />
                      )
                    },
                    {
                      title: "K-40",
                      dataIndex: "k",
                      render: (_, row) => (
                        <InputNumber value={row.k} min={0} onChange={(value) => updateRow(row.key, "k", value)} />
                      )
                    },
                    {
                      title: "",
                      key: "action",
                      width: 88,
                      render: (_, row) => (
                        <Button danger size="small" disabled={rows.length <= 2} onClick={() => removeRow(row.key)}>
                          删除
                        </Button>
                      )
                    }
                  ]}
                />
              </div>
              <div className="measurement-actions">
                <Button size="small" block onClick={addRow}>
                  添加次数
                </Button>
                <Button type="primary" size="small" block loading={loading} onClick={calculate}>
                  计算
                </Button>
              </div>
            </Card>

            <Card title="校准参数 / 判定标准值" className="panel compact-panel">
              <Table<CalibrationRow>
                className="calibration-table"
                pagination={false}
                size="small"
                rowKey="key"
                dataSource={[
                  { key: "ra", name: "Ra", ...defaultCalibration.ra },
                  { key: "th", name: "Th", ...defaultCalibration.th },
                  { key: "k", name: "K", ...defaultCalibration.k }
                ]}
                columns={[
                  { title: "核素", dataIndex: "name", align: "center" },
                  { title: "a", dataIndex: "factor", align: "center" },
                  {
                    title: "U",
                    dataIndex: "expanded_uncertainty_percent",
                    align: "center",
                    render: (value: number) => `${value}%`
                  },
                  { title: "k", dataIndex: "coverage_factor", align: "center" }
                ]}
              />
              <div className="limits-form">
                <div className="limit-field">
                  <span className="limit-label">IRa 标准值</span>
                  <InputNumber
                    value={limits.ira_limit}
                    min={0}
                    step={0.1}
                    onChange={(value) => setLimits((current) => ({ ...current, ira_limit: value ?? 0 }))}
                  />
                </div>
                <div className="limit-field">
                  <span className="limit-label">Ir 标准值</span>
                  <InputNumber
                    value={limits.ir_limit}
                    min={0}
                    step={0.1}
                    onChange={(value) => setLimits((current) => ({ ...current, ir_limit: value ?? 0 }))}
                  />
                </div>
              </div>
            </Card>
          </div>

          {error ? <Alert type="error" message={error} showIcon /> : null}

          <div className="results-area">
            {result ? (
              <div className="results-row">
              <Card title="计算结果（GUM 法）" className="panel">
                <div className="result-grid">
                  <ResultTile title="IRa" value={result.ira.value} uncertainty={result.ira.relative_uncertainty_percent} />
                  <ResultTile title="Ir" value={result.ir.value} uncertainty={result.ir.relative_uncertainty_percent} />
                  <div className="result-tile conclusion-tile">
                    <span>判定</span>
                    <Tag color={result.conclusion === "Ok" ? "success" : "warning"}>
                      {conclusionText[result.conclusion]}
                    </Tag>
                  </div>
                </div>
                <Table<ResultRow>
                  pagination={false}
                  rowKey="name"
                  size="small"
                  dataSource={[
                    { name: "Ra-226", ...result.ra },
                    { name: "Th-232", ...result.th },
                    { name: "K-40", ...result.k }
                  ]}
                  columns={[
                    { title: "核素", dataIndex: "name" },
                    { title: "均值", dataIndex: "mean_measured", render: (value: number) => formatNumber(value) },
                    { title: "校准活度", dataIndex: "mean_calibrated", render: (value: number) => formatNumber(value) },
                    { title: "A 类", dataIndex: "type_a_uncertainty", render: (value: number) => formatNumber(value) },
                    { title: "B 类相对", dataIndex: "type_b_relative", render: (value) => formatNumber(value * 100, 3) + "%" },
                    { title: "合成", dataIndex: "combined_uncertainty", render: (value: number) => formatNumber(value) }
                  ]}
                />
              </Card>

              <Card title={`蒙特卡洛仿真（MCM，${result.mcm.iterations} 次）`} className="panel">
                <div className="result-grid">
                  <div className="result-tile">
                    <span>综合合格概率</span>
                    <strong>{formatPercent(result.mcm.overall_pass_probability)}</strong>
                    <small>IRa 与 Ir 同时合格</small>
                  </div>
                  <div className="result-tile">
                    <span>综合不合格概率</span>
                    <strong>{formatPercent(result.mcm.overall_fail_probability)}</strong>
                    <small>任一指数超标</small>
                  </div>
                  <div className="result-tile conclusion-tile">
                    <span>仿真判定</span>
                    <Tag color={result.mcm.overall_pass_probability >= 0.95 ? "success" : "warning"}>
                      {result.mcm.overall_pass_probability >= 0.95 ? "合格" : "不合格风险"}
                    </Tag>
                  </div>
                </div>
                <Table<McmRow>
                  pagination={false}
                  rowKey="name"
                  size="small"
                  dataSource={[
                    { name: "IRa", ...result.mcm.ira },
                    { name: "Ir", ...result.mcm.ir }
                  ]}
                  columns={[
                    { title: "指数", dataIndex: "name" },
                    { title: "平均值", dataIndex: "mean", render: (value: number) => formatNumber(value) },
                    { title: "标准偏差", dataIndex: "std_dev", render: (value: number) => formatNumber(value) },
                    { title: "P2.5", dataIndex: "p2_5", render: (value: number) => formatNumber(value) },
                    { title: "P97.5", dataIndex: "p97_5", render: (value: number) => formatNumber(value) },
                    { title: "标准值", dataIndex: "standard_value", render: (value: number) => formatNumber(value, 2) },
                    {
                      title: "合格概率",
                      dataIndex: "pass_probability",
                      render: (value: number) => (
                        <Tag color={value >= 0.95 ? "success" : "warning"}>{formatPercent(value)}</Tag>
                      )
                    }
                  ]}
                />
              </Card>
              </div>
            ) : (
              <div className="results-placeholder">请计算后查看结果</div>
            )}
          </div>
        </section>
      </main>
    </ConfigProvider>
  );
}

function ResultTile(props: { title: string; value: number; uncertainty: number }) {
  return (
    <div className="result-tile">
      <span>{props.title}</span>
      <strong>{formatNumber(props.value)}</strong>
      <small>相对不确定度 {formatNumber(props.uncertainty, 2)}%</small>
    </div>
  );
}

export { App };
