
import React, { useState, useEffect } from 'react';
import { MemoryBank, TagData } from '../types';
import { Lock, HardDriveDownload, HardDriveUpload, Search, RefreshCw, ChevronDown, Tag } from 'lucide-react';
import { hexStringToBytes, hexToAscii, asciiToHex } from '../utils/crc16';

interface Props {
  tags: TagData[];
  onScan: () => void;
  isScanning: boolean;
  onRead: (bank: MemoryBank, ptr: number, len: number, password: string, targetEpc: string) => Promise<void>;
  onWrite: (bank: MemoryBank, ptr: number, data: string, password: string, targetEpc: string) => Promise<void>;
  onWriteEpc: (newEpc: string, password: string) => Promise<void>;
  selectedEpc: string; // From parent (legacy), we will use local state mainly
  readResult: string | null;
}

export const MemoryPanel: React.FC<Props> = ({ tags, onScan, isScanning, onRead, onWrite, onWriteEpc, selectedEpc: initialEpc, readResult }) => {
  const [targetEpc, setTargetEpc] = useState(initialEpc);
  const [bank, setBank] = useState<MemoryBank>(MemoryBank.EPC);
  const [ptr, setPtr] = useState(2); // Default to 2 for EPC bank
  const [len, setLen] = useState(4);
  const [password, setPassword] = useState("00000000");
  const [writeData, setWriteData] = useState("");
  
  // Unified Data Mode: Controls both Read display and Write input interpretation
  const [dataMode, setDataMode] = useState<'hex' | 'ascii'>('hex');

  // Update local state if parent prop changes (optional sync)
  useEffect(() => {
    if (initialEpc) setTargetEpc(initialEpc);
  }, [initialEpc]);

  // If tags list updates and we don't have a target, auto-select the first one
  useEffect(() => {
    if (!targetEpc && tags.length > 0) {
      setTargetEpc(tags[0].epc);
    }
  }, [tags, targetEpc]);

  // Auto-update Pointer default based on Bank to prevent Parameter Errors
  useEffect(() => {
    if (bank === MemoryBank.EPC) {
      setPtr(2); // Start at 2 to skip CRC (0) and PC (1) which are often protected
    } else {
      setPtr(0);
    }
  }, [bank]);

  const handleRead = () => {
    if (!targetEpc) {
      alert("Please select or scan a tag first.");
      return;
    }
    onRead(bank, ptr, len, password, targetEpc);
  };

  const toggleDataMode = (newMode: 'hex' | 'ascii') => {
    if (newMode === dataMode) return;
    
    // Convert current Write Input Data to match new mode
    // This prevents the user from having to manually convert what they just typed
    if (newMode === 'ascii') {
       // Switching Hex -> Ascii
       setWriteData(hexToAscii(writeData));
    } else {
       // Switching Ascii -> Hex
       setWriteData(asciiToHex(writeData));
    }
    setDataMode(newMode);
  };

  const getHexForWrite = () => {
    if (dataMode === 'ascii') {
      return asciiToHex(writeData);
    }
    return writeData;
  };

  const handleWrite = () => {
    if (!targetEpc) {
      alert("Please select or scan a tag first.");
      return;
    }
    
    const hexPayload = getHexForWrite();
    onWrite(bank, ptr, hexPayload, password, targetEpc);
  };

  const handleInitializeEpc = () => {
     const hexPayload = getHexForWrite();

     // Validate locally but allow error logging
     if (!hexStringToBytes(hexPayload)) {
       // Pass invalid data to parent to trigger the "Invalid EPC Data" log
       onWriteEpc(hexPayload, password);
       return;
     }

     // Confirm with user only if data looks valid
     if (confirm("This will overwrite the EPC of a single tag in the field using Command 0x04. Proceed?")) {
        onWriteEpc(hexPayload, password);
     }
  };

  return (
    <div className="bg-white p-6 rounded-xl shadow-sm border border-slate-200">
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
        <h2 className="text-lg font-bold text-slate-800 flex items-center gap-2">
          <HardDriveDownload className="text-blue-600" />
          Memory Operations
        </h2>

        {/* Unified Mode Toggle */}
        <div className="bg-slate-100 p-1 rounded-lg flex items-center self-start sm:self-auto">
          <button 
            onClick={() => toggleDataMode('hex')}
            className={`px-3 py-1.5 text-xs font-bold rounded-md transition-all ${dataMode === 'hex' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-500 hover:text-slate-700'}`}
          >
            HEX Mode
          </button>
          <button 
            onClick={() => toggleDataMode('ascii')}
            className={`px-3 py-1.5 text-xs font-bold rounded-md transition-all ${dataMode === 'ascii' ? 'bg-white text-blue-600 shadow-sm' : 'text-slate-500 hover:text-slate-700'}`}
          >
            ASCII Mode
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Configuration Column */}
        <div className="space-y-5">
          
          {/* Tag Selection Area */}
          <div className="bg-slate-50 p-4 rounded-lg border border-slate-200">
            <label className="block text-sm font-bold text-slate-700 mb-2">Target Tag (Filter)</label>
            <div className="flex gap-2 mb-2">
              <div className="relative flex-1">
                 <input 
                  type="text" 
                  value={targetEpc} 
                  onChange={(e) => setTargetEpc(e.target.value)}
                  placeholder="Scan or type EPC..."
                  className="w-full bg-white border border-slate-300 text-slate-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 font-mono"
                />
                {tags.length > 0 && (
                  <div className="absolute right-2 top-2.5 pointer-events-none text-slate-400">
                    <ChevronDown className="w-4 h-4" />
                  </div>
                )}
                {/* Invisible Select overlay for dropdown behavior */}
                {tags.length > 0 && (
                   <select 
                      onChange={(e) => setTargetEpc(e.target.value)}
                      value={targetEpc}
                      className="absolute inset-0 opacity-0 cursor-pointer"
                   >
                     <option value="" disabled>Select from list...</option>
                     {tags.map(t => (
                       <option key={t.epc} value={t.epc}>{t.epc} (Count: {t.count})</option>
                     ))}
                   </select>
                )}
              </div>
              
              <button 
                type="button"
                onClick={onScan}
                className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors flex items-center gap-2 whitespace-nowrap ${
                   isScanning 
                   ? 'bg-amber-100 text-amber-700 border border-amber-200' 
                   : 'bg-blue-600 text-white hover:bg-blue-700'
                }`}
              >
                {isScanning ? <RefreshCw className="w-4 h-4 animate-spin" /> : <Search className="w-4 h-4" />}
                {isScanning ? 'Stop' : 'Scan'}
              </button>
            </div>
            <p className="text-xs text-slate-500">
              {tags.length > 0 
                ? `${tags.length} tags found. Select one to target.` 
                : "Click Scan to find nearby tags."}
            </p>
          </div>

          <div>
            <label className="block text-sm font-medium text-slate-600 mb-1">Access Password (8 Hex Chars)</label>
            <div className="relative">
              <input 
                type="text" 
                value={password}
                onChange={e => setPassword(e.target.value)}
                maxLength={8}
                className="w-full bg-white border border-slate-300 text-slate-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 pl-9 font-mono"
              />
              <Lock className="w-4 h-4 text-slate-400 absolute left-3 top-3" />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium text-slate-600 mb-1">Memory Bank</label>
              <select 
                value={bank} 
                onChange={e => setBank(Number(e.target.value))}
                className="w-full bg-white border border-slate-300 text-slate-900 text-sm rounded-lg p-2.5"
              >
                <option value={MemoryBank.RESERVED}>Reserved</option>
                <option value={MemoryBank.EPC}>EPC</option>
                <option value={MemoryBank.TID}>TID</option>
                <option value={MemoryBank.USER}>User</option>
              </select>
            </div>
            <div className="grid grid-cols-2 gap-2">
              <div>
                <label className="block text-xs font-medium text-slate-500 mb-1">Start (Word)</label>
                <input 
                  type="number" 
                  value={ptr}
                  onChange={e => setPtr(Number(e.target.value))}
                  className="w-full bg-white border border-slate-300 text-sm rounded-lg p-2.5"
                />
              </div>
              <div>
                <label className="block text-xs font-medium text-slate-500 mb-1">Len (Word)</label>
                <input 
                  type="number" 
                  value={len}
                  onChange={e => setLen(Number(e.target.value))}
                  className="w-full bg-white border border-slate-300 text-sm rounded-lg p-2.5"
                />
              </div>
            </div>
          </div>
          
          {bank === MemoryBank.EPC && (
             <div className="text-xs text-amber-600 bg-amber-50 p-2 rounded border border-amber-100">
                <strong>Note:</strong> Start Address 0 is CRC, 1 is PC. Writing to these may fail (Error 0xFF). EPC data typically starts at address 2.
             </div>
          )}
        </div>

        {/* Action Column */}
        <div className="flex flex-col gap-4">
           {/* Read Section */}
           <div className="p-4 bg-slate-50 rounded-lg border border-slate-200 flex-1 flex flex-col">
              <label className="text-sm font-semibold text-slate-700 mb-2">
                Read Data <span className="text-xs font-normal text-slate-400">({dataMode.toUpperCase()})</span>
              </label>
              
              <div className="flex-1 bg-white border border-slate-300 rounded p-2 mb-2 font-mono text-xs text-slate-600 break-all overflow-y-auto min-h-[60px]">
                {readResult 
                  ? (dataMode === 'hex' ? readResult : hexToAscii(readResult))
                  : "No data read..."
                }
              </div>
              
              <button 
                type="button"
                onClick={handleRead}
                className="w-full bg-white border border-slate-300 hover:bg-slate-50 text-slate-700 font-medium py-2 rounded-lg text-sm transition-colors flex items-center justify-center gap-2"
              >
                <HardDriveDownload className="w-4 h-4" /> Read Memory
              </button>
           </div>

           {/* Write Section */}
           <div className="p-4 bg-slate-50 rounded-lg border border-slate-200">
              <label className="text-sm font-semibold text-slate-700 mb-2">
                Write Data <span className="text-xs font-normal text-slate-400">({dataMode.toUpperCase()})</span>
              </label>
              
              <input 
                type="text" 
                value={writeData}
                onChange={e => setWriteData(e.target.value)}
                placeholder={dataMode === 'hex' ? "e.g., A1 B2 C3..." : "Type text here..."}
                className="w-full bg-white border border-slate-300 text-sm rounded p-2 mb-2 font-mono"
              />
              <div className="grid grid-cols-2 gap-2">
                <button 
                  type="button"
                  onClick={handleWrite}
                  className="bg-slate-800 hover:bg-slate-900 text-white font-medium py-2 rounded-lg text-sm transition-colors flex items-center justify-center gap-2"
                  title="Writes data to the selected bank/address (Cmd 0x03)"
                >
                  <HardDriveUpload className="w-4 h-4" /> Write Mem
                </button>
                
                {bank === MemoryBank.EPC && (
                  <button 
                    type="button"
                    onClick={handleInitializeEpc}
                    className="bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 rounded-lg text-sm transition-colors flex items-center justify-center gap-2"
                    title="Overwrites EPC of a SINGLE tag in field (Cmd 0x04)"
                  >
                    <Tag className="w-4 h-4" /> Write EPC
                  </button>
                )}
              </div>
           </div>
        </div>
      </div>
    </div>
  );
};
