import { useState, useRef, useCallback, useEffect } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Video, Camera, Square, Loader2, AlertTriangle, Shield, Eye } from 'lucide-react';
import { toast } from 'sonner';

const csrfToken = () =>
  (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? '';

interface Hazard {
  id?: string;
  frame_number: number;
  frame_screenshot_url: string;
  hazard_description: string;
  hazard_category: string;
  severity: string;
  likelihood: string;
  risk_score: number;
  control_measures: string;
  confidence: number;
}

const SEVERITY_COLORS: Record<string, string> = {
  low: 'bg-emerald-500/10 text-emerald-700 border-emerald-500/30',
  medium: 'bg-amber-500/10 text-amber-700 border-amber-500/30',
  high: 'bg-orange-500/10 text-orange-700 border-orange-500/30',
  critical: 'bg-destructive/10 text-destructive border-destructive/30',
};

const CATEGORY_LABELS: Record<string, string> = {
  ppe: 'PPE', falls: 'Falls', electrical: 'Electrical', fire: 'Fire',
  manual_handling: 'Manual Handling', slip_trip: 'Slip/Trip', chemical: 'Chemical',
  machinery: 'Machinery', ergonomics: 'Ergonomics', housekeeping: 'Housekeeping',
  signage: 'Signage', access: 'Access', structural: 'Structural',
  environmental: 'Environmental', other: 'Other',
};

const AIRiskAssessor = ({ companyId }: { companyId: string }) => {
  const [title, setTitle] = useState('Live Site Inspection');
  const [environmentType, setEnvironmentType] = useState('construction');
  const [location, setLocation] = useState('');
  const [assessmentId, setAssessmentId] = useState<string | null>(null);
  const [isScanning, setIsScanning] = useState(false);
  const [isAnalysing, setIsAnalysing] = useState(false);
  const [hazards, setHazards] = useState<Hazard[]>([]);
  const [overallRisk, setOverallRisk] = useState<string | null>(null);
  const [sceneSummary, setSceneSummary] = useState<string | null>(null);
  const [frameCount, setFrameCount] = useState(0);
  const [cameraError, setCameraError] = useState<string | null>(null);

  const videoRef = useRef<HTMLVideoElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const streamRef = useRef<MediaStream | null>(null);
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const startCamera = useCallback(async () => {
    try {
      setCameraError(null);
      const stream = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: 'environment', width: { ideal: 1280 }, height: { ideal: 720 } },
      });
      streamRef.current = stream;
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
      }
    } catch (err: any) {
      setCameraError('Camera access denied. Please allow camera permissions.');
      console.error('Camera error:', err);
    }
  }, []);

  const stopCamera = useCallback(() => {
    streamRef.current?.getTracks().forEach((t) => t.stop());
    streamRef.current = null;
    if (videoRef.current) videoRef.current.srcObject = null;
  }, []);

  const captureFrame = useCallback((): string | null => {
    const video = videoRef.current;
    const canvas = canvasRef.current;
    if (!video || !canvas) return null;

    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    const ctx = canvas.getContext('2d');
    if (!ctx) return null;
    ctx.drawImage(video, 0, 0);
    return canvas.toDataURL('image/jpeg', 0.8).split(',')[1]; // base64 only
  }, []);

  const analyseFrame = useCallback(
    async (currentAssessmentId: string, frameNum: number) => {
      const base64 = captureFrame();
      if (!base64) return;

      setIsAnalysing(true);
      try {
        const existingDescriptions = hazards.map((h) => h.hazard_description);
        const res = await fetch('/api/admin/functions/analyse-risk-frame', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
          body: JSON.stringify({
            assessment_id: currentAssessmentId,
            frame_number: frameNum,
            frame_base64: base64,
            environment_type: environmentType,
            existing_hazards: existingDescriptions,
          }),
        });

        if (!res.ok) throw new Error('Failed to analyse frame');
        const data = await res.json();
        if (data?.error) throw new Error(data.error);

        if (data.hazards?.length) {
          setHazards((prev) => [...prev, ...data.hazards]);
        }
        if (data.overall_risk_level) setOverallRisk(data.overall_risk_level);
        if (data.scene_summary) setSceneSummary(data.scene_summary);
      } catch (e: any) {
        console.error('Analysis error:', e);
        // Don't toast every frame error - just log
      } finally {
        setIsAnalysing(false);
      }
    },
    [captureFrame, environmentType, hazards],
  );

  const startInspection = async () => {
    // Create assessment in DB
    const res = await fetch('/api/admin/risk-assessments', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
      body: JSON.stringify({
        company_id: companyId,
        title,
        environment_type: environmentType,
        location: location || null,
        status: 'in_progress',
      }),
    });

    if (!res.ok) {
      toast.error('Failed to create assessment');
      return;
    }

    const assessment = await res.json().catch(() => null);
    if (!assessment) {
      toast.error('Failed to create assessment');
      return;
    }

    const aId = (assessment as any).id;
    setAssessmentId(aId);
    setHazards([]);
    setOverallRisk(null);
    setSceneSummary(null);
    setFrameCount(0);
    setIsScanning(true);

    await startCamera();

    // Wait for camera to warm up, then start auto-capture every 8s
    setTimeout(() => {
      let fNum = 0;
      intervalRef.current = setInterval(() => {
        fNum += 1;
        setFrameCount(fNum);
        analyseFrame(aId, fNum);
      }, 8000);
    }, 2000);

    // Log usage
    await fetch('/api/admin/service-usage-log', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
      body: JSON.stringify({
        company_id: companyId,
        service_type: 'ai_risk_assessor',
        action: 'live_inspection_started',
        input_data: { title, environmentType, location },
      }),
    });

    toast.success('Inspection started — analysing frames every 8 seconds');
  };

  const stopInspection = async () => {
    if (intervalRef.current) clearInterval(intervalRef.current);
    intervalRef.current = null;
    stopCamera();
    setIsScanning(false);

    if (assessmentId) {
      await fetch(`/api/admin/risk-assessments/${encodeURIComponent(assessmentId)}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
        body: JSON.stringify({ status: 'completed' }),
      });
    }
    toast.success('Inspection completed');
  };

  const captureNow = () => {
    if (!assessmentId) return;
    const nextFrame = frameCount + 1;
    setFrameCount(nextFrame);
    analyseFrame(assessmentId, nextFrame);
  };

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
      stopCamera();
    };
  }, [stopCamera]);

  const uniqueCategories = [...new Set(hazards.map((h) => h.hazard_category))];
  const maxRiskScore = hazards.length > 0 ? Math.max(...hazards.map((h) => h.risk_score)) : 0;

  return (
    <div className="space-y-6">
      {/* Setup / Camera Card */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Video className="h-5 w-5 text-primary" /> AI Live Risk Assessor
          </CardTitle>
          <p className="text-sm text-muted-foreground">
            Point your camera at the site — AI analyses frames every 8 seconds to identify hazards in real time
          </p>
        </CardHeader>
        <CardContent className="space-y-4">
          {!isScanning ? (
            <>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                <div>
                  <label className="text-sm font-medium text-foreground">Inspection Title</label>
                  <Input value={title} onChange={(e) => setTitle(e.target.value)} />
                </div>
                <div>
                  <label className="text-sm font-medium text-foreground">Environment</label>
                  <Select value={environmentType} onValueChange={setEnvironmentType}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="construction">Construction</SelectItem>
                      <SelectItem value="retail_warehouse">Retail / Warehouse</SelectItem>
                      <SelectItem value="office">Office</SelectItem>
                      <SelectItem value="industrial">Industrial</SelectItem>
                      <SelectItem value="general">General</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div>
                  <label className="text-sm font-medium text-foreground">Location</label>
                  <Input placeholder="e.g. Building A, Floor 2" value={location} onChange={(e) => setLocation(e.target.value)} />
                </div>
              </div>
              <Button onClick={startInspection} className="gap-2">
                <Camera className="h-4 w-4" /> Start Live Inspection
              </Button>
            </>
          ) : (
            <div className="space-y-4">
              {/* Camera feed */}
              <div className="relative bg-black rounded-lg overflow-hidden aspect-video">
                <video ref={videoRef} autoPlay playsInline muted className="w-full h-full object-cover" />
                {isAnalysing && (
                  <div className="absolute top-3 right-3 bg-background/80 backdrop-blur px-3 py-1.5 rounded-full flex items-center gap-2 text-sm">
                    <Loader2 className="h-4 w-4 animate-spin text-primary" />
                    <span className="text-foreground">Analysing...</span>
                  </div>
                )}
                <div className="absolute bottom-3 left-3 bg-background/80 backdrop-blur px-3 py-1.5 rounded-full text-sm text-foreground">
                  Frame #{frameCount} · {hazards.length} hazard{hazards.length !== 1 ? 's' : ''} found
                </div>
                {overallRisk && (
                  <div className="absolute top-3 left-3">
                    <Badge className={`${SEVERITY_COLORS[overallRisk]} text-sm font-semibold border`}>
                      {overallRisk.toUpperCase()} RISK
                    </Badge>
                  </div>
                )}
              </div>
              {cameraError && (
                <p className="text-sm text-destructive">{cameraError}</p>
              )}
              <canvas ref={canvasRef} className="hidden" />
              <div className="flex gap-2">
                <Button variant="outline" onClick={captureNow} disabled={isAnalysing} className="gap-2">
                  <Eye className="h-4 w-4" /> Capture & Analyse Now
                </Button>
                <Button variant="destructive" onClick={stopInspection} className="gap-2">
                  <Square className="h-4 w-4" /> Stop Inspection
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Scene Summary */}
      {sceneSummary && (
        <Card>
          <CardContent className="py-4">
            <p className="text-sm text-foreground"><strong>Scene Summary:</strong> {sceneSummary}</p>
          </CardContent>
        </Card>
      )}

      {/* Hazards Feed */}
      {hazards.length > 0 && (
        <Card>
          <CardHeader>
            <div className="flex items-center justify-between">
              <CardTitle className="flex items-center gap-2">
                <AlertTriangle className="h-5 w-5" /> Identified Hazards ({hazards.length})
              </CardTitle>
              <div className="flex gap-2 flex-wrap">
                {uniqueCategories.map((cat) => (
                  <Badge key={cat} variant="outline" className="text-xs">
                    {CATEGORY_LABELS[cat] || cat}
                  </Badge>
                ))}
              </div>
            </div>
          </CardHeader>
          <CardContent>
            <ScrollArea className="max-h-[500px]">
              <div className="space-y-3">
                {hazards.map((h, i) => (
                  <div key={i} className="border rounded-lg p-4 space-y-2">
                    <div className="flex items-start justify-between gap-4">
                      <div className="flex-1">
                        <div className="flex items-center gap-2 mb-1">
                          <Badge className={`${SEVERITY_COLORS[h.severity]} text-xs border`}>
                            {h.severity.toUpperCase()}
                          </Badge>
                          <Badge variant="outline" className="text-xs">
                            {CATEGORY_LABELS[h.hazard_category] || h.hazard_category}
                          </Badge>
                          <span className="text-xs text-muted-foreground">
                            Risk Score: {h.risk_score}/20 · Frame #{h.frame_number} · Confidence: {Math.round(h.confidence * 100)}%
                          </span>
                        </div>
                        <p className="text-sm font-medium text-foreground">{h.hazard_description}</p>
                      </div>
                      {h.frame_screenshot_url && (
                        <img
                          src={h.frame_screenshot_url}
                          alt={`Frame ${h.frame_number}`}
                          className="w-24 h-16 object-cover rounded border"
                        />
                      )}
                    </div>
                    <div className="flex items-center gap-2 text-xs text-muted-foreground">
                      <Shield className="h-3 w-3" />
                      <span><strong>Controls:</strong> {h.control_measures}</span>
                    </div>
                  </div>
                ))}
              </div>
            </ScrollArea>
          </CardContent>
        </Card>
      )}

      {/* Risk Score Summary */}
      {hazards.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle className="text-sm">Risk Score Matrix</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
              <div>
                <p className="text-2xl font-bold text-foreground">{hazards.length}</p>
                <p className="text-xs text-muted-foreground">Total Hazards</p>
              </div>
              <div>
                <p className="text-2xl font-bold text-foreground">{maxRiskScore}/20</p>
                <p className="text-xs text-muted-foreground">Max Risk Score</p>
              </div>
              <div>
                <p className="text-2xl font-bold text-foreground">{hazards.filter((h) => h.severity === 'critical' || h.severity === 'high').length}</p>
                <p className="text-xs text-muted-foreground">High/Critical</p>
              </div>
              <div>
                <p className="text-2xl font-bold text-foreground">{frameCount}</p>
                <p className="text-xs text-muted-foreground">Frames Analysed</p>
              </div>
            </div>
          </CardContent>
        </Card>
      )}
    </div>
  );
};

export default AIRiskAssessor;
