import fs from 'fs';

const decoderPath = 'C:/X/workspace/jumpa.id/vc/lib/xcu-quantum-decoder.ts';
let decoderContent = fs.readFileSync(decoderPath, 'utf-8');

// 1. Add Auto-Pilot Properties
const modesOld = `public videoEngineMode: "canvas" | "webcodecs" = "canvas";
\tpublic audioEngineMode: "pcm" | "xcu-neural" = "pcm";`;

const modesNew = `public videoEngineMode: "auto" | "canvas" | "webcodecs" = "auto";
\tpublic audioEngineMode: "auto" | "pcm" | "xcu-neural" = "auto";
\tpublic activeVideoCodec: string = "STANDBY";
\tpublic activeAudioCodec: string = "STANDBY";
\tpublic currentBandwidth: number = 0;
\tprivate autoPilotInterval: any = null;
\tprivate isSwappingEncoder: boolean = false;`;

decoderContent = decoderContent.replace(modesOld, modesNew);

// 2. Modify activateUplink to set initial active codecs and start auto-pilot
if (!decoderContent.includes("startQuantumAutoPilot")) {
    const uplinkEnd = `this.ws!.send(initPacket);
\t\t\t\t}
\t\t\t} catch (e) {
\t\t\t\tconsole.error("Camera error", e);
\t\t\t}
\t\t}`;
    
    const startAutoPilotCall = `this.ws!.send(initPacket);
\t\t\t\t}
\t\t\t\t
\t\t\t\tthis.activeVideoCodec = this.videoCodecString ? this.videoCodecString.split('.')[0].toUpperCase() : 'CANVAS';
\t\t\t\tthis.activeAudioCodec = this.audioEngineMode === 'xcu-neural' || this.audioEngineMode === 'auto' ? 'XCU NEURAL' : 'PCM';
\t\t\t\tthis.startQuantumAutoPilot();
\t\t\t\t
\t\t\t} catch (e) {
\t\t\t\tconsole.error("Camera error", e);
\t\t\t}
\t\t}`;
    decoderContent = decoderContent.replace(uplinkEnd, startAutoPilotCall);
}

// 3. Add the AutoPilot logic
const autoPilotLogic = `\tpublic startQuantumAutoPilot() {
\t\tif (this.autoPilotInterval) clearInterval(this.autoPilotInterval);
\t\tthis.autoPilotInterval = setInterval(async () => {
\t\t\t// Real Network Metrik dari V8 Engine
\t\t\tconst conn = (navigator as any).connection;
\t\t\tconst downlink = conn ? conn.downlink : 10; // Mbps
\t\t\tthis.currentBandwidth = downlink;
\t\t\t
\t\t\tif (this.isSwappingEncoder) return;

\t\t\t// --- AUTO VIDEO ---
\t\t\tif (this.videoEngineMode === 'auto' && this.videoEncoder) {
\t\t\t\tlet targetCodec = this.videoCodecString;
\t\t\t\tlet targetBitrate = 1_000_000;
\t\t\t\t
\t\t\t\tif (downlink > 3) {
\t\t\t\t\ttargetCodec = "vp09.00.10.08"; // VP9
\t\t\t\t\ttargetBitrate = 2_000_000;
\t\t\t\t} else if (downlink >= 1) {
\t\t\t\t\ttargetCodec = "vp8"; // VP8
\t\t\t\t\ttargetBitrate = 800_000;
\t\t\t\t} else {
\t\t\t\t\ttargetCodec = "avc1.42E01F"; // H.264
\t\t\t\t\ttargetBitrate = 300_000;
\t\t\t\t}
\t\t\t\t
\t\t\t\tif (this.videoCodecString !== targetCodec) {
\t\t\t\t\tthis.isSwappingEncoder = true;
\t\t\t\t\tconsole.log(\`[AUTO-PILOT] Bandwidth \${downlink} Mbps. Hot-Swapping Video ke \${targetCodec}\`);
\t\t\t\t\ttry {
\t\t\t\t\t\t(this.videoEncoder as any).close();
\t\t\t\t\t\tthis.videoCodecString = targetCodec;
\t\t\t\t\t\tthis.activeVideoCodec = targetCodec.split('.')[0].toUpperCase();
\t\t\t\t\t\tthis.videoEncoder = new (window as any).VideoEncoder({
\t\t\t\t\t\t\toutput: (chunk: any, metadata: any) => this.handleVideoChunk(chunk, metadata),
\t\t\t\t\t\t\terror: (e: any) => console.error("AutoPilot Video Error", e)
\t\t\t\t\t\t});
\t\t\t\t\t\t(this.videoEncoder as any).configure({
\t\t\t\t\t\t\tcodec: this.videoCodecString,
\t\t\t\t\t\t\twidth: 640, height: 480, bitrate: targetBitrate, framerate: 30
\t\t\t\t\t\t});
\t\t\t\t\t} catch(e) {}
\t\t\t\t\tthis.isSwappingEncoder = false;
\t\t\t\t}
\t\t\t}

\t\t\t// --- AUTO AUDIO ---
\t\t\tif (this.audioEngineMode === 'auto') {
\t\t\t\t// Auto-pilot ensures XCU Neural is active if bandwidth > 0.1, fallback to PCM only if extreme
\t\t\t\tconst wantNeural = downlink > 0.1;
\t\t\t\tconst currentIsNeural = this.audioEncoder !== null;
\t\t\t\tif (wantNeural && !currentIsNeural) {
\t\t\t\t\t// Re-init Audio Encoder (XCU Neural)
\t\t\t\t\tthis.isSwappingEncoder = true;
\t\t\t\t\ttry {
\t\t\t\t\t\tthis.audioEncoder = new (window as any).AudioEncoder({
\t\t\t\t\t\t\toutput: (chunk: any) => this.handleAudioChunk(chunk),
\t\t\t\t\t\t\terror: (e: any) => console.error("AutoPilot Audio Error", e)
\t\t\t\t\t\t});
\t\t\t\t\t\t(this.audioEncoder as any).configure({
\t\t\t\t\t\t\tcodec: 'opus', sampleRate: 48000, numberOfChannels: 1, bitrate: 32000
\t\t\t\t\t\t});
\t\t\t\t\t\tthis.activeAudioCodec = 'XCU NEURAL';
\t\t\t\t\t} catch(e) {}
\t\t\t\t\tthis.isSwappingEncoder = false;
\t\t\t\t} else if (!wantNeural && currentIsNeural) {
\t\t\t\t\ttry { (this.audioEncoder as any).close(); } catch(e) {}
\t\t\t\t\tthis.audioEncoder = null;
\t\t\t\t\tthis.activeAudioCodec = 'RAW PCM';
\t\t\t\t}
\t\t\t}
\t\t}, 3000);
\t}

\tprivate handleVideoChunk(chunk: any, metadata: any) {
\t\tif (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
\t\tconst chunkData = new Uint8Array(chunk.byteLength);
\t\tchunk.copyTo(chunkData);
\t\tconst packetLen = 8 + chunkData.length;
\t\tconst packet = new Uint8Array(packetLen);
\t\tpacket[0] = chunk.type === "key" ? 3 : 4;
\t\tpacket[1] = 0;
\t\tconst view = new DataView(packet.buffer);
\t\tview.setUint16(2, this.participantId, true);
\t\tview.setUint32(4, packetLen - 8, true);
\t\tpacket.set(chunkData, 8);
\t\tthis.ws.send(packet);
\t}

\tprivate handleAudioChunk(chunk: any) {
\t\tif (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
\t\tconst chunkData = new Uint8Array(chunk.byteLength);
\t\tchunk.copyTo(chunkData);
\t\tconst packetLen = 8 + 1 + chunkData.length;
\t\tconst packet = new Uint8Array(packetLen);
\t\tpacket[0] = 2; // FRAME_AUDIO
\t\tpacket[1] = 1;
\t\tconst view = new DataView(packet.buffer);
\t\tview.setUint16(2, this.participantId, true);
\t\tview.setUint32(4, packetLen - 8, true);
\t\tpacket[8] = 1; // Opus Codec ID
\t\tpacket.set(chunkData, 9);
\t\tthis.ws.send(packet);
\t}
`;

if (!decoderContent.includes("startQuantumAutoPilot")) {
    decoderContent = decoderContent.replace(`public async deactivateUplink() {`, autoPilotLogic + `\n\tpublic async deactivateUplink() {`);
    
    // Clear interval in deactivateUplink
    decoderContent = decoderContent.replace(`if (this.videoEncoder) {`, `if (this.autoPilotInterval) clearInterval(this.autoPilotInterval);\n\t\tif (this.videoEncoder) {`);
}

// Modify existing audioEncoder init in activateUplink to use handleAudioChunk
decoderContent = decoderContent.replace(
    /output: \(chunk: any\) => \{[\s\S]*?this\.ws!\.send\(packet\);\n\s*\},/m,
    `output: (chunk: any) => this.handleAudioChunk(chunk),`
);

// Add hotSwap logic types for AUTO
decoderContent = decoderContent.replace(
    /public async hotSwapVideoEngine\(mode: "canvas" \| "webcodecs"\)/g,
    `public async hotSwapVideoEngine(mode: "auto" | "canvas" | "webcodecs")`
);
decoderContent = decoderContent.replace(
    /public async hotSwapAudioEngine\(mode: "pcm" \| "xcu-neural"\)/g,
    `public async hotSwapAudioEngine(mode: "auto" | "pcm" | "xcu-neural")`
);

fs.writeFileSync(decoderPath, decoderContent, 'utf-8');

// UI Update: xcuRoom.tsx
const roomPath = 'C:/X/workspace/jumpa.id/vc/components/xcuRoom.tsx';
let roomContent = fs.readFileSync(roomPath, 'utf-8');

roomContent = roomContent.replace(
    `const [videoEngineMode, setVideoEngineMode] = useState<'canvas' | 'webcodecs'>('webcodecs');\n  const [audioEngineMode, setAudioEngineMode] = useState<'pcm' | 'xcu-neural'>('xcu-neural');`,
    `const [videoEngineMode, setVideoEngineMode] = useState<'auto'|'canvas'|'webcodecs'>('auto');\n  const [audioEngineMode, setAudioEngineMode] = useState<'auto'|'pcm'|'xcu-neural'>('auto');\n  const [autoPilotMetrics, setAutoPilotMetrics] = useState({ vCodec: 'STANDBY', aCodec: 'STANDBY', bw: 0 });`
);

// We need a useEffect to constantly poll the autoPilotMetrics from the matrix
const pollLogic = `useEffect(() => {
    let interval: NodeJS.Timeout;
    if (matrixRef.current && (videoEngineMode === 'auto' || audioEngineMode === 'auto')) {
        interval = setInterval(() => {
            setAutoPilotMetrics({
                vCodec: matrixRef.current!.activeVideoCodec,
                aCodec: matrixRef.current!.activeAudioCodec,
                bw: matrixRef.current!.currentBandwidth
            });
        }, 1000);
    }
    return () => clearInterval(interval);
  }, [videoEngineMode, audioEngineMode]);`;

roomContent = roomContent.replace(`const [participants, setParticipants] = useState<any[]>([]);`, pollLogic + `\n  const [participants, setParticipants] = useState<any[]>([]);`);

const toggleVideoEngine = `const handleToggleEngine = () => {
      const nextMode = videoEngineMode === 'auto' ? 'webcodecs' : (videoEngineMode === 'webcodecs' ? 'canvas' : 'auto');
      setVideoEngineMode(nextMode);
      if (matrixRef.current) {
          matrixRef.current.hotSwapVideoEngine(nextMode);
      }
  };`;
roomContent = roomContent.replace(/const handleToggleEngine = \(\) => \{[\s\S]*?\};\n  const handleToggleAudioEngine/, toggleVideoEngine + '\n  const handleToggleAudioEngine');

const toggleAudioEngine = `const handleToggleAudioEngine = () => {
      const nextMode = audioEngineMode === 'auto' ? 'xcu-neural' : (audioEngineMode === 'xcu-neural' ? 'pcm' : 'auto');
      setAudioEngineMode(nextMode);
      if (matrixRef.current) {
          matrixRef.current.hotSwapAudioEngine(nextMode);
      }
  };`;
roomContent = roomContent.replace(/const handleToggleAudioEngine = \(\) => \{[\s\S]*?\};\n  const handleToggleScreenShare/, toggleAudioEngine + '\n  const handleToggleScreenShare');

// The UI replace
const newCapsuleUI = `<!-- Quantum Engine Capsule -->
              <div className="flex bg-slate-800/50 p-1 rounded-xl border border-slate-700/50 shadow-inner">
                  {/* Video Segment */}
                  <button onClick={handleToggleEngine} className={\`flex flex-col items-center justify-center w-20 h-14 rounded-lg transition-all duration-300 \${videoEngineMode === 'auto' ? 'bg-amber-900/60 text-amber-400 shadow-[0_0_15px_rgba(251,191,36,0.6)] z-10' : (videoEngineMode === 'webcodecs' ? 'bg-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(34,211,238,0.5)] z-10' : 'text-slate-400 hover:bg-slate-700/50')}\`}>
                     <div className="relative">
                         <svg className={\`w-5 h-5 mb-1 \${videoEngineMode === 'auto' ? 'animate-ping' : ''}\`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
                         </svg>
                     </div>
                     <span className="text-[8px] leading-tight text-center font-bold whitespace-nowrap">
                         {videoEngineMode === 'auto' ? \`AUTO (\${autoPilotMetrics.vCodec} \${autoPilotMetrics.bw.toFixed(1)}M)\` : (videoEngineMode === 'webcodecs' ? 'GPU VIDEO' : 'CPU VIDEO')}
                     </span>
                  </button>

                  {/* Divider */}
                  <div className="w-[1px] bg-slate-700 mx-1 self-center h-8"></div>

                  {/* Audio Segment */}
                  <button onClick={handleToggleAudioEngine} className={\`flex flex-col items-center justify-center w-20 h-14 rounded-lg transition-all duration-300 \${audioEngineMode === 'auto' ? 'bg-amber-900/60 text-amber-400 shadow-[0_0_15px_rgba(251,191,36,0.6)] z-10' : (audioEngineMode === 'xcu-neural' ? 'bg-fuchsia-900/60 text-fuchsia-400 shadow-[0_0_15px_rgba(217,70,239,0.5)] z-10' : 'text-slate-400 hover:bg-slate-700/50')}\`}>
                     <div className="relative">
                         <svg className={\`w-5 h-5 mb-1 \${audioEngineMode === 'auto' ? 'animate-pulse' : ''}\`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"></path>
                         </svg>
                     </div>
                     <span className="text-[8px] leading-tight text-center font-bold whitespace-nowrap">
                         {audioEngineMode === 'auto' ? \`AUTO (\${autoPilotMetrics.aCodec})\` : (audioEngineMode === 'xcu-neural' ? 'XCU NEURAL' : 'RAW PCM')}
                     </span>
                  </button>
              </div>`;

roomContent = roomContent.replace(/<!-- Quantum Engine Capsule -->[\s\S]*?<\/div>/, newCapsuleUI);

fs.writeFileSync(roomPath, roomContent, 'utf-8');

console.log("Auto Codec Quantum Matrix Update Complete");
