'use client';

import { useMemo, useState } from 'react';
import ToolShell from '@/components/toolkit/ToolShell';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { cn } from '@/lib/utils';

type Mode = 'vector' | 'raster' | 'irradiance' | 'pulse';

function num(v: string, d = 0): number {
  const n = Number(v);
  return Number.isFinite(n) ? n : d;
}
function clamp(v: number, lo: number, hi: number) {
  return Math.max(lo, Math.min(hi, v));
}

/** Default curve parameters based on rated power (very rough, editable). */
function defaultCurveForRatedW(W: number) {
  // Peak frequency guess (kHz). Tune these to your hardware fleet.
  let fPeak = 50;
  if (W <= 35) fPeak = 25;
  else if (W <= 60) fPeak = 50;
  else if (W <= 90) fPeak = 75;
  else fPeak = 100;

  // Log-normal width parameter (dimensionless). Smaller = narrower peak.
  const sigma = 0.35;
  return { fPeak, sigma };
}

/** Log-normal shaped efficiency curve normalized to 1 at fPeak. */
function etaOfF(f_kHz: number, fPeak_kHz: number, sigma: number) {
  const f = Math.max(f_kHz, 0.1);
  const r = Math.log(f / Math.max(fPeak_kHz, 0.1));
  const eta = Math.exp(-0.5 * (r / Math.max(sigma, 0.05)) ** 2);
  // Keep within [0.1, 1] to avoid absurd zeros; adjust if you want tails to hit 0.
  return clamp(eta, 0.1, 1);
}

/** Area factor from field (proxy for spot area scaling) */
function areaFactorFromField(fieldSrc: number, fieldDst: number) {
  if (fieldSrc <= 0 || fieldDst <= 0) return 1;
  const r = fieldDst / fieldSrc;
  return r * r;
}

export default function Page() {
  // MODE
  const [mode, setMode] = useState<Mode>('vector');

  // SOURCE machine/lens
  const [wSrc, setWSrc] = useState('100');      // rated W
  const [pSrc, setPSrc] = useState('50');       // %
  const [vSrc, setVSrc] = useState('300');      // mm/s
  const [hSrc, setHSrc] = useState('0.1');      // mm (raster line spacing)
  const [fSrc, setFSrc] = useState('30');       // kHz
  const [tauSrc, setTauSrc] = useState('100');  // ns pulse width
  const [fieldSrc, setFieldSrc] = useState('110'); // mm

  // DEST machine/lens
  const [wDst, setWDst] = useState('50');       // rated W
  const [vDst, setVDst] = useState('300');      // mm/s
  const [hDst, setHDst] = useState('0.1');      // mm
  const [fDst, setFDst] = useState('30');       // kHz
  const [tauDst, setTauDst] = useState('100');  // ns
  const [fieldDst, setFieldDst] = useState('70');  // mm

  // Curve tuning / advanced
  const [advanced, setAdvanced] = useState(false);
  const srcDefaults = defaultCurveForRatedW(num(wSrc, 50));
  const dstDefaults = defaultCurveForRatedW(num(wDst, 50));
  const [fPeakSrc, setFPeakSrc] = useState(String(srcDefaults.fPeak));
  const [sigmaSrc, setSigmaSrc] = useState(String(srcDefaults.sigma));
  const [fPeakDst, setFPeakDst] = useState(String(dstDefaults.fPeak));
  const [sigmaDst, setSigmaDst] = useState(String(dstDefaults.sigma));

  // Prefer adjusting speed/freq instead of exceeding 100% power
  const [preferSpeedAdjust, setPreferSpeedAdjust] = useState(true);

  const result = useMemo(() => {
    const W1 = Math.max(num(wSrc, 1), 0.1);
    const W2 = Math.max(num(wDst, 1), 0.1);
    const p1 = clamp(num(pSrc, 0), 0, 100) / 100; // 0..1
    const v1 = Math.max(num(vSrc, 0), 0.0001);
    const v2 = Math.max(num(vDst, 0), 0.0001);
    const h1 = Math.max(num(hSrc, 0), 0.000001);
    const h2 = Math.max(num(hDst, 0), 0.000001);
    const f1k = Math.max(num(fSrc, 0), 0.1);
    const f2k = Math.max(num(fDst, 0), 0.1);
    const tau1_ns = Math.max(num(tauSrc, 0), 0.1);
    const tau2_ns = Math.max(num(tauDst, 0), 0.1);
    const aFac = areaFactorFromField(num(fieldSrc, 0), num(fieldDst, 0));

    const fpk1 = Math.max(num(fPeakSrc, defaultCurveForRatedW(W1).fPeak), 0.1);
    const sig1 = Math.max(num(sigmaSrc, defaultCurveForRatedW(W1).sigma), 0.05);
    const fpk2 = Math.max(num(fPeakDst, defaultCurveForRatedW(W2).fPeak), 0.1);
    const sig2 = Math.max(num(sigmaDst, defaultCurveForRatedW(W2).sigma), 0.05);

    // Efficiency factors (0..1)
    const eta1 = etaOfF(f1k, fpk1, sig1);
    const eta2 = etaOfF(f2k, fpk2, sig2);

    // Effective average power (W) after frequency efficiency
    const P1eff = W1 * p1 * eta1;

    let p2Frac = p1; // destination power fraction (0..1)
    let suggestedSpeed: number | undefined;
    let suggestedFreq_kHz: number | undefined;

    // Helper: compute required P2eff for each match, then map to power%
    const powerPercentFromEff = (P2effReq: number) => {
      // P2eff = W2 * p2 * eta2  => p2 = P2eff / (W2*eta2)
      return P2effReq / (W2 * eta2);
    };

    if (mode === 'vector') {
      // Match energy per length: P1eff / v1 = P2eff / v2
      const P2effReq = P1eff * (v2 / v1);
      p2Frac = powerPercentFromEff(P2effReq);
      if (preferSpeedAdjust && p2Frac > 1) {
        suggestedSpeed = v1 * (W2 * eta2) / (W1 * eta1 * p1); // from p2<=1
        p2Frac = 1;
      }
    } else if (mode === 'raster') {
      // Match energy per area: P1eff/(v1*h1) = P2eff/(v2*h2)
      const P2effReq = P1eff * ((v2 * h2) / (v1 * h1));
      p2Frac = powerPercentFromEff(P2effReq);
      if (preferSpeedAdjust && p2Frac > 1) {
        suggestedSpeed = v1 * (W2 * eta2) * (h1 / h2) / (W1 * eta1 * p1);
        p2Frac = 1;
      }
    } else if (mode === 'irradiance') {
      // Match irradiance: (P1eff/A1) = (P2eff/A2)  => P2eff = P1eff*(A2/A1)
      const P2effReq = P1eff * aFac;
      p2Frac = powerPercentFromEff(P2effReq);
      // no speed suggestion; consider lens/field change if >100%
    } else if (mode === 'pulse') {
      // Match pulse energy: Ep1 = P1eff / f1  (kHz → Hz)
      const f1 = f1k * 1e3, f2 = f2k * 1e3;
      const Ep1 = P1eff / f1; // J
      // Require P2eff = Ep1 * f2
      const P2effReq = Ep1 * f2;
      p2Frac = powerPercentFromEff(P2effReq);

      if (preferSpeedAdjust && p2Frac > 1) {
        // Suggest lowering f2 to keep p2<=1: P2eff_max = W2*eta2*1
        // f2_req = P2eff_max / Ep1
        const f2_req = (W2 * eta2) / Ep1; // Hz
        suggestedFreq_kHz = Math.max(f2_req / 1e3, 0.1);
        p2Frac = 1;
      }
    }

    // Compute pulse metrics (for display) using **destination** settings
    const p2Clamped = clamp(p2Frac, 0, 2);
    const P2eff = W2 * p2Clamped * eta2;
    const f2Hz = f2k * 1e3;
    const tau2_s = tau2_ns * 1e-9;
    const Ep2 = P2eff / f2Hz; // J
    const Ppeak2 = Ep2 / Math.max(tau2_s, 1e-12); // W, shape factor ~1 assumed

    return {
      p2Percent: clamp(p2Clamped * 100, 0, 200),
      suggestedSpeed,
      suggestedFreq_kHz,
      eta1,
      eta2,
      P1eff,
      P2eff,
      Ep2,
      Ppeak2,
      aFac,
    };
  }, [
    mode, wSrc, wDst, pSrc, vSrc, vDst, hSrc, hDst, fSrc, fDst, tauSrc, tauDst,
    fieldSrc, fieldDst, preferSpeedAdjust, fPeakSrc, sigmaSrc, fPeakDst, sigmaDst,
  ]);

  return (
    <ToolShell
      title="Power, Frequency & Lens Scaler"
      description="Match settings across different lasers and lenses using effective power with a frequency efficiency curve. Includes pulse width to report pulse energy and peak power."
    >
      <Card className="mb-6">
        <CardHeader>
          <CardTitle>Match Mode</CardTitle>
        </CardHeader>
        <CardContent className="grid gap-4 md:grid-cols-2">
          <div>
            <Label className="text-sm">Quantity to Match</Label>
            <Select value={mode} onValueChange={(v: Mode) => setMode(v)}>
              <SelectTrigger><SelectValue placeholder="Mode" /></SelectTrigger>
              <SelectContent>
                <SelectItem value="vector">Vector: Energy per length (J/mm)</SelectItem>
                <SelectItem value="raster">Raster: Energy per area (J/mm²)</SelectItem>
                <SelectItem value="irradiance">Irradiance: W/mm² (spot/field)</SelectItem>
                <SelectItem value="pulse">Pulse energy: J (fiber)</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <label className="flex items-center gap-2">
            <input
              id="preferSpeed"
              type="checkbox"
              className="h-4 w-4"
              checked={preferSpeedAdjust}
              onChange={(e) => setPreferSpeedAdjust(e.target.checked)}
            />
            <span className="text-sm">If Power % &gt; 100, prefer adjusting speed/frequency</span>
          </label>
        </CardContent>
      </Card>

      {/* Source */}
      <Card className="mb-6">
        <CardHeader>
          <CardTitle>Source (what you have)</CardTitle>
        </CardHeader>
        <CardContent className="grid gap-4 md:grid-cols-3">
          <div>
            <Label className="text-sm">Rated power (W)</Label>
            <Input value={wSrc} onChange={(e) => setWSrc(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Power (%)</Label>
            <Input value={pSrc} onChange={(e) => setPSrc(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Frequency (kHz)</Label>
            <Input value={fSrc} onChange={(e) => setFSrc(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Pulse width (ns)</Label>
            <Input value={tauSrc} onChange={(e) => setTauSrc(e.target.value)} inputMode="decimal" />
          </div>
          <div className={cn(mode !== 'irradiance' ? 'block' : 'hidden')}>
            <Label className="text-sm">Speed (mm/s)</Label>
            <Input value={vSrc} onChange={(e) => setVSrc(e.target.value)} inputMode="decimal" />
          </div>
          <div className={cn(mode === 'raster' ? 'block' : 'hidden')}>
            <Label className="text-sm">Line spacing h (mm)</Label>
            <Input value={hSrc} onChange={(e) => setHSrc(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Lens field size (mm)</Label>
            <Input value={fieldSrc} onChange={(e) => setFieldSrc(e.target.value)} inputMode="decimal" />
          </div>
        </CardContent>

        <CardContent className="pt-0">
          <button
            className="text-xs underline text-muted-foreground"
            onClick={() => setAdvanced((s) => !s)}
          >
            {advanced ? 'Hide' : 'Show'} advanced frequency curve
          </button>
          <div className={cn('mt-3 grid gap-4 md:grid-cols-3', advanced ? 'block' : 'hidden')}>
            <div>
              <Label className="text-sm">Peak freq fₚ (kHz)</Label>
              <Input value={fPeakSrc} onChange={(e) => setFPeakSrc(e.target.value)} inputMode="decimal" />
            </div>
            <div>
              <Label className="text-sm">Curve width σ (log-normal)</Label>
              <Input value={sigmaSrc} onChange={(e) => setSigmaSrc(e.target.value)} inputMode="decimal" />
            </div>
            <div className="flex items-end text-xs text-muted-foreground">
              η(f) is log-normal; 1.0 at fₚ, rolls off by σ.
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Destination */}
      <Card className="mb-6">
        <CardHeader>
          <CardTitle>Destination (what you want to run on)</CardTitle>
        </CardHeader>
        <CardContent className="grid gap-4 md:grid-cols-3">
          <div>
            <Label className="text-sm">Rated power (W)</Label>
            <Input value={wDst} onChange={(e) => setWDst(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Frequency (kHz)</Label>
            <Input value={fDst} onChange={(e) => setFDst(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Pulse width (ns)</Label>
            <Input value={tauDst} onChange={(e) => setTauDst(e.target.value)} inputMode="decimal" />
          </div>
          <div className={cn(mode !== 'irradiance' ? 'block' : 'hidden')}>
            <Label className="text-sm">Speed (mm/s)</Label>
            <Input value={vDst} onChange={(e) => setVDst(e.target.value)} inputMode="decimal" />
          </div>
          <div className={cn(mode === 'raster' ? 'block' : 'hidden')}>
            <Label className="text-sm">Line spacing h (mm)</Label>
            <Input value={hDst} onChange={(e) => setHDst(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <Label className="text-sm">Lens field size (mm)</Label>
            <Input value={fieldDst} onChange={(e) => setFieldDst(e.target.value)} inputMode="decimal" />
          </div>
        </CardContent>

        <CardContent className={cn('pt-0', advanced ? 'block' : 'hidden')}>
          <div className="mt-3 grid gap-4 md:grid-cols-3">
            <div>
              <Label className="text-sm">Peak freq fₚ (kHz)</Label>
              <Input value={fPeakDst} onChange={(e) => setFPeakDst(e.target.value)} inputMode="decimal" />
            </div>
            <div>
              <Label className="text-sm">Curve width σ (log-normal)</Label>
              <Input value={sigmaDst} onChange={(e) => setSigmaDst(e.target.value)} inputMode="decimal" />
            </div>
            <div className="flex items-end text-xs text-muted-foreground">
              Adjust if you know your machine’s real power–frequency curve.
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Result */}
      <Card>
        <CardHeader>
          <CardTitle>Result</CardTitle>
        </CardHeader>
        <CardContent className="space-y-2">
          <div className="text-2xl font-semibold">
            Suggested Power (dest): {result.p2Percent.toFixed(1)}%
          </div>

          {typeof result.suggestedSpeed === 'number' && mode !== 'pulse' && (
            <p className="text-sm">
              To keep Power ≤ 100%, try destination speed ≈{' '}
              <span className="font-medium">{result.suggestedSpeed.toFixed(1)} mm/s</span>.
            </p>
          )}

          {typeof result.suggestedFreq_kHz === 'number' && mode === 'pulse' && (
            <p className="text-sm">
              To keep Power ≤ 100%, try destination frequency ≈{' '}
              <span className="font-medium">{result.suggestedFreq_kHz.toFixed(0)} kHz</span>.
            </p>
          )}

          <div className="mt-3 grid gap-2 md:grid-cols-3 text-sm">
            <div>
              <div className="text-muted-foreground">η(f) source / dest</div>
              <div className="font-medium">{result.eta1.toFixed(3)} / {result.eta2.toFixed(3)}</div>
            </div>
            <div>
              <div className="text-muted-foreground">Dest pulse energy</div>
              <div className="font-medium">
                {(result.Ep2 >= 1e-3 ? (result.Ep2 * 1e3).toFixed(3) + ' mJ' : (result.Ep2 * 1e6).toFixed(1) + ' µJ')}
              </div>
            </div>
            <div>
              <div className="text-muted-foreground">Dest peak power</div>
              <div className="font-medium">{(result.Ppeak2 / 1000).toFixed(1)} kW</div>
            </div>
          </div>

          <p className="text-xs text-muted-foreground mt-2">
            Assumptions: Effective power includes a frequency efficiency factor η(f). Peak power uses a rectangular pulse
            approximation (shape factor ≈ 1). For real MOPA sources, pulse shape and
            true power–frequency maps vary by model; adjust f<sub>p</sub> and σ if you have vendor curves.
          </p>
        </CardContent>
      </Card>
    </ToolShell>
  );
}

