import React, { useState, useRef } from 'react';

type Mode = 'chords' | 'secants';

interface Point {
  x: number;
  y: number;
}

const PowerOfPointWidget: React.FC = () => {
  const [mode, setMode] = useState<Mode>('chords');
  
  // -- Common State --
  const svgRef = useRef<SVGSVGElement>(null);
  const isDragging = useRef<string | null>(null);
  const center = { x: 200, y: 180 };
  const radius = 100;

  // -- Chords Mode State --
  // Store angles for points A, B, C, D on the circle
  const [chordAngles, setChordAngles] = useState({
      a: 220, b: 40,  // Chord 1
      c: 140, d: 320  // Chord 2
  });

  // -- Secants Mode State --
  // P is external point.
  // Secant 1 defined by angle theta1 (offset from center-P line)
  // Secant 2 defined by angle theta2
  const [secantState, setSecantState] = useState({
      px: 380, py: 180, // Point P
      theta1: 15,       // Angle offset for secant 1
  });

  // --- Helper Math ---
  const getPosOnCircle = (deg: number) => ({
      x: center.x + radius * Math.cos(deg * Math.PI / 180),
      y: center.y + radius * Math.sin(deg * Math.PI / 180)
  });

  const dist = (p1: Point, p2: Point) => Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));

  const getIntersection = (p1: Point, p2: Point, p3: Point, p4: Point) => {
      // Line AB represented as a1x + b1y = c1
      const a1 = p2.y - p1.y;
      const b1 = p1.x - p2.x;
      const c1 = a1 * p1.x + b1 * p1.y;
      // Line CD represented as a2x + b2y = c2
      const a2 = p4.y - p3.y;
      const b2 = p3.x - p4.x;
      const c2 = a2 * p3.x + b2 * p3.y;
      const determinant = a1 * b2 - a2 * b1;
      if (Math.abs(determinant) < 0.001) return null; // Parallel
      const x = (b2 * c1 - b1 * c2) / determinant;
      const y = (a1 * c2 - a2 * c1) / determinant;
      // Check if inside circle
      if (dist({x,y}, center) > radius + 1) return null;
      return { x, y };
  };

  // --- Interaction Handlers ---
  const handleChordDrag = (e: React.MouseEvent, key: string) => {
      if (!svgRef.current) return;
      const rect = svgRef.current.getBoundingClientRect();
      const dx = e.clientX - rect.left - center.x;
      const dy = e.clientY - rect.top - center.y;
      let deg = Math.atan2(dy, dx) * 180 / Math.PI;
      if (deg < 0) deg += 360;
      setChordAngles(prev => ({ ...prev, [key]: deg }));
  };

  const handleSecantDrag = (e: React.MouseEvent) => {
      if (!svgRef.current) return;
      const rect = svgRef.current.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      
      if (isDragging.current === 'P') {
         // Constrain P outside
         const dx = x - center.x;
         const dy = y - center.y;
         const d = Math.sqrt(dx*dx + dy*dy);
         if (d > radius + 20) {
             setSecantState(prev => ({...prev, px: x, py: y}));
         } else {
             const ang = Math.atan2(dy, dx);
             setSecantState(prev => ({
                 ...prev, 
                 px: center.x + (radius+20)*Math.cos(ang),
                 py: center.y + (radius+20)*Math.sin(ang)
             }));
         }
      } else if (isDragging.current === 'SecantEnd') {
          // Calculate angle relative to PO line
          // Vector PO
          const pdx = center.x - secantState.px;
          const pdy = center.y - secantState.py;
          const poAngle = Math.atan2(pdy, pdx);
          
          // Vector PA (mouse to P)
          const mdx = x - secantState.px;
          const mdy = y - secantState.py;
          const mAngle = Math.atan2(mdy, mdx);
          
          let diff = (mAngle - poAngle) * 180 / Math.PI;
          // Normalize to -180 to 180
          while (diff > 180) diff -= 360;
          while (diff < -180) diff += 360;
          
          // Clamp to hit circle. Max angle is asin(R/dist)
          const distPO = Math.sqrt(pdx*pdx + pdy*pdy);
          const maxAngle = Math.asin(radius/distPO) * 180 / Math.PI;
          
          // Clamp
          const clamped = Math.max(-maxAngle + 1, Math.min(maxAngle - 1, diff));
          setSecantState(prev => ({...prev, theta1: clamped}));
      }
  };

  // --- Render Helpers ---
  const renderChords = () => {
      const A = getPosOnCircle(chordAngles.a);
      const B = getPosOnCircle(chordAngles.b);
      const C = getPosOnCircle(chordAngles.c);
      const D = getPosOnCircle(chordAngles.d);
      
      const E = getIntersection(A, B, C, D);
      
      const valid = !!E;
      const ae = valid ? dist(A, E) : 0;
      const eb = valid ? dist(E, B) : 0;
      const ce = valid ? dist(C, E) : 0;
      const ed = valid ? dist(E, D) : 0;

      const points = [
        { k: 'a', p: A, l: 'A', c: '#7c3aed' },
        { k: 'b', p: B, l: 'B', c: '#7c3aed' },
        { k: 'c', p: C, l: 'C', c: '#059669' },
        { k: 'd', p: D, l: 'D', c: '#059669' }
      ];

      return (
        <>
           <line x1={A.x} y1={A.y} x2={B.x} y2={B.y} stroke="#7c3aed" strokeWidth="3" />
           <line x1={C.x} y1={C.y} x2={D.x} y2={D.y} stroke="#059669" strokeWidth="3" />

           {/* Points */}
           {points.map((pt) => (
              <g key={pt.k} onMouseDown={() => isDragging.current = pt.k} className="cursor-pointer hover:scale-110 transition-transform">
                  <circle cx={pt.p.x} cy={pt.p.y} r="15" fill="transparent" />
                  <circle cx={pt.p.x} cy={pt.p.y} r="6" fill={pt.c} stroke="white" strokeWidth="2" />
                  <text x={pt.p.x} y={pt.p.y - 12} textAnchor="middle" className="text-sm font-bold fill-slate-700">{pt.l}</text>
              </g>
           ))}

           {valid && (
             <>
                <circle cx={E.x} cy={E.y} r="4" fill="#0f172a" />
                <text x={E.x + 10} y={E.y} className="text-xs font-bold fill-slate-500">E</text>
             </>
           )}

           {/* Info Panel */}
           <div className="absolute top-4 left-4 bg-white/90 p-4 rounded-xl border border-slate-200 shadow-sm backdrop-blur-sm pointer-events-none select-none">
               {!valid ? (
                   <p className="text-red-500 font-bold">Chords must intersect inside!</p>
               ) : (
                   <div className="space-y-3 font-mono text-sm">
                       <div className="flex gap-4">
                           <div>
                               <div className="text-xs font-bold text-violet-600">Purple Chord</div>
                               <div>{ae.toFixed(0)} × {eb.toFixed(0)} = <strong>{(ae*eb).toFixed(0)}</strong></div>
                           </div>
                       </div>
                       <div className="flex gap-4">
                           <div>
                               <div className="text-xs font-bold text-emerald-600">Green Chord</div>
                               <div>{ce.toFixed(0)} × {ed.toFixed(0)} = <strong>{(ce*ed).toFixed(0)}</strong></div>
                           </div>
                       </div>
                       <div className="h-px bg-slate-200"></div>
                       <p className="text-slate-500 text-xs text-center font-sans">
                           AE · EB = CE · ED
                       </p>
                   </div>
               )}
           </div>
        </>
      );
  };

  const renderSecant = () => {
      const { px, py, theta1 } = secantState;
      // Calculate Tangent Point T (Upper)
      const dx = px - center.x;
      const dy = py - center.y;
      const distPO = Math.sqrt(dx*dx + dy*dy);
      const anglePO = Math.atan2(dy, dx);
      const angleOffset = Math.acos(radius/distPO);
      const tAngle = anglePO - angleOffset;
      const T = {
          x: center.x + radius * Math.cos(tAngle),
          y: center.y + radius * Math.sin(tAngle)
      };
      const tangentLen = Math.sqrt(distPO*distPO - radius*radius);

      // Calculate Secant Intersection Points
      // Secant Line angle
      const secantAngle = anglePO + theta1 * Math.PI / 180;
      
      const vx = px - center.x;
      const vy = py - center.y;
      const cos = Math.cos(secantAngle);
      const sin = Math.sin(secantAngle);
      // t^2 + 2(V.D)t + (V^2 - R^2) = 0
      const b = 2 * (vx * cos + vy * sin);
      const c = vx*vx + vy*vy - radius*radius;
      const det = b*b - 4*c;
      
      let A = {x:0, y:0}, B = {x:0, y:0};
      let valid = false;
      
      if (det > 0) {
          const tFar = (-b - Math.sqrt(det)) / 2;
          const tNear = (-b + Math.sqrt(det)) / 2; 

          // A is Near (External part)
          A = { x: px + tNear * cos, y: py + tNear * sin };
          // B is Far (Whole secant endpoint)
          B = { x: px + tFar * cos, y: py + tFar * sin };
          valid = true;
      }

      const distPA = valid ? dist({x:px, y:py}, A) : 0;
      const distPB = valid ? dist({x:px, y:py}, B) : 0;

      return (
          <>
             {/* Tangent Line */}
             <line x1={px} y1={py} x2={T.x} y2={T.y} stroke="#e11d48" strokeWidth="3" />
             <circle cx={T.x} cy={T.y} r="5" fill="#e11d48" />
             <text x={T.x} y={T.y - 10} className="text-xs font-bold fill-rose-600">T</text>
             
             {/* Secant Line (Draw full segment P to B) */}
             {valid && <line x1={px} y1={py} x2={B.x} y2={B.y} stroke="#7c3aed" strokeWidth="3" />}
             {valid && (
                 <>
                    {/* Point A (Near/External) */}
                    <circle cx={A.x} cy={A.y} r="5" fill="#7c3aed" />
                    <text x={A.x + 15} y={A.y} className="text-xs font-bold fill-violet-600">A</text>
                    
                    {/* Point B (Far/Whole) */}
                    <circle cx={B.x} cy={B.y} r="5" fill="#7c3aed" />
                    <text x={B.x - 15} y={B.y} className="text-xs font-bold fill-violet-600">B</text>
                 </>
             )}

             {/* Point P */}
             <g onMouseDown={() => isDragging.current = 'P'} className="cursor-grab active:cursor-grabbing">
                 <circle cx={px} cy={py} r="15" fill="transparent" />
                 <circle cx={px} cy={py} r="6" fill="#0f172a" stroke="white" strokeWidth="2" />
                 <text x={px + 10} y={py} className="text-sm font-bold fill-slate-800">P</text>
             </g>
             
             {/* Drag Handle for Secant Angle (at B, the far end) */}
             {valid && (
                 <circle 
                   cx={B.x} cy={B.y} r="12" fill="transparent" stroke="white" strokeWidth="2" strokeDasharray="2,2" 
                   className="cursor-pointer hover:stroke-violet-400"
                   onMouseDown={() => isDragging.current = 'SecantEnd'}
                 />
             )}

             {/* Info */}
             <div className="absolute top-4 left-4 bg-white/90 p-4 rounded-xl border border-slate-200 shadow-sm backdrop-blur-sm pointer-events-none select-none">
                 <div className="space-y-3 font-mono text-sm">
                     <div className="mb-2">
                         <div className="text-xs font-bold text-rose-600 uppercase">Tangent² (PT²)</div>
                         <div>{tangentLen.toFixed(0)}² = <strong>{(tangentLen*tangentLen).toFixed(0)}</strong></div>
                     </div>
                     <div>
                         <div className="text-xs font-bold text-violet-600 uppercase">Secant (PA · PB)</div>
                         <div className="flex items-center gap-1">
                             <span title="External Part (PA)">{distPA.toFixed(0)}</span>
                             <span className="text-slate-400">×</span>
                             <span title="Whole Secant (PB)">{distPB.toFixed(0)}</span>
                             <span className="text-slate-400">=</span>
                             <strong>{(distPA*distPB).toFixed(0)}</strong>
                         </div>
                     </div>
                     <div className="h-px bg-slate-200 my-2"></div>
                     <p className="text-slate-500 text-xs text-center font-sans">
                         Tangent² = External × Whole
                     </p>
                 </div>
             </div>
          </>
      );
  };

  const handleMouseMove = (e: React.MouseEvent) => {
      if (!isDragging.current) return;
      if (mode === 'chords') {
          // Check if dragging specific points
          if (['a','b','c','d'].includes(isDragging.current as string)) {
              handleChordDrag(e, isDragging.current as string);
          }
      } else {
          handleSecantDrag(e);
      }
  };

  return (
    <div className="bg-white p-6 rounded-xl shadow-lg border border-slate-200">
       <div className="flex gap-4 mb-6 justify-center">
           <button 
             onClick={() => setMode('chords')}
             className={`px-4 py-2 rounded-full font-bold text-sm transition-all ${mode === 'chords' ? 'bg-slate-900 text-white shadow-md' : 'bg-slate-100 text-slate-500 hover:bg-slate-200'}`}
           >
               Intersecting Chords
           </button>
           <button 
             onClick={() => setMode('secants')}
             className={`px-4 py-2 rounded-full font-bold text-sm transition-all ${mode === 'secants' ? 'bg-slate-900 text-white shadow-md' : 'bg-slate-100 text-slate-500 hover:bg-slate-200'}`}
           >
               Tangent-Secant
           </button>
       </div>

       <div className="relative flex justify-center bg-slate-50 rounded-xl border border-slate-100 overflow-hidden">
           <svg 
             ref={svgRef}
             width="500" height="360"
             className="select-none"
             onMouseMove={handleMouseMove}
             onMouseUp={() => isDragging.current = null}
             onMouseLeave={() => isDragging.current = null}
           >
               <defs>
                   <pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
                       <path d="M 20 0 L 0 0 0 20" fill="none" stroke="#e2e8f0" strokeWidth="0.5"/>
                   </pattern>
               </defs>
               <rect width="100%" height="100%" fill="url(#grid)" />
               
               {/* Circle */}
               <circle cx={center.x} cy={center.y} r={radius} fill="white" stroke="#94a3b8" strokeWidth="2" />
               <circle cx={center.x} cy={center.y} r="3" fill="#cbd5e1" />

               {mode === 'chords' ? renderChords() : renderSecant()}
           </svg>
       </div>
       
       <div className="mt-4 text-center text-sm text-slate-500">
           {mode === 'chords' 
             ? "Drag the colored points along the circle."
             : "Drag point P or the secant endpoint B."
           }
       </div>
    </div>
  );
};

export default PowerOfPointWidget;