import { useRef, useState } from "react";
import ReactCrop, { Crop, PixelCrop, centerCrop, makeAspectCrop } from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";
import { Camera, Copy, RotateCcw, Save } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { useToast } from "@/hooks/use-toast";
import { apiRequest } from "@/lib/queryClient";
import { PatientTable } from "@/components/patients/patient-table";
import { Patient } from "@repo/db/types";

function getCroppedDataUrl(image: HTMLImageElement, crop: PixelCrop): string {
  const scaleX = image.naturalWidth / image.width;
  const scaleY = image.naturalHeight / image.height;

  const canvas = document.createElement("canvas");
  canvas.width = crop.width * scaleX;
  canvas.height = crop.height * scaleY;
  const ctx = canvas.getContext("2d");
  ctx?.drawImage(
    image,
    crop.x * scaleX,
    crop.y * scaleY,
    crop.width * scaleX,
    crop.height * scaleY,
    0,
    0,
    canvas.width,
    canvas.height
  );
  return canvas.toDataURL("image/png");
}

export default function AiCopyAgentPage() {
  const { toast } = useToast();
  const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null);
  const [screenshot, setScreenshot] = useState<string | null>(null);
  const [fileName, setFileName] = useState("");
  const [crop, setCrop] = useState<Crop>();
  const [completedCrop, setCompletedCrop] = useState<PixelCrop>();
  const [isCapturing, setIsCapturing] = useState(false);
  const [countdown, setCountdown] = useState<number | null>(null);
  const [isSaving, setIsSaving] = useState(false);
  const streamRef = useRef<MediaStream | null>(null);
  const imgRef = useRef<HTMLImageElement | null>(null);

  const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {
    imgRef.current = e.currentTarget;
    const { width, height } = e.currentTarget;
    const fullCrop = centerCrop(
      makeAspectCrop({ unit: "%", width: 100 }, width / height, width, height),
      width,
      height
    );
    setCrop(fullCrop);
    setCompletedCrop({
      unit: "px",
      x: 0,
      y: 0,
      width,
      height,
    });
  };

  const stopStream = () => {
    streamRef.current?.getTracks().forEach((track) => track.stop());
    streamRef.current = null;
  };

  const handleCapture = async () => {
    setIsCapturing(true);
    try {
      const stream = await navigator.mediaDevices.getDisplayMedia({
        video: { displaySurface: "monitor" },
      });
      streamRef.current = stream;

      const video = document.createElement("video");
      video.srcObject = stream;
      video.muted = true;
      await video.play();
      await new Promise<void>((resolve) => {
        if (video.readyState >= 2) resolve();
        else video.onloadeddata = () => resolve();
      });

      for (let secondsLeft = 3; secondsLeft > 0; secondsLeft--) {
        setCountdown(secondsLeft);
        await new Promise((resolve) => setTimeout(resolve, 1000));
      }
      setCountdown(null);

      const canvas = document.createElement("canvas");
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      const ctx = canvas.getContext("2d");
      ctx?.drawImage(video, 0, 0, canvas.width, canvas.height);

      stopStream();
      setScreenshot(canvas.toDataURL("image/png"));
      setFileName(`screenshot_${Date.now()}`);
    } catch (error) {
      console.error("Error capturing screenshot:", error);
      const name = error instanceof Error ? error.name : "";
      const description =
        name === "NotAllowedError"
          ? "Screen share permission was denied or the picker was cancelled."
          : name === "NotFoundError"
          ? "No screen/window source was available to capture."
          : !navigator.mediaDevices?.getDisplayMedia
          ? "Screen capture isn't supported in this browser."
          : (error instanceof Error ? error.message : "Screen capture failed.");
      toast({
        title: "Screenshot failed",
        description,
        variant: "destructive",
      });
      stopStream();
    } finally {
      setIsCapturing(false);
      setCountdown(null);
    }
  };

  const handleRetake = () => {
    setScreenshot(null);
    setFileName("");
    setCrop(undefined);
    setCompletedCrop(undefined);
    handleCapture();
  };

  const handleSave = async () => {
    if (!screenshot || !selectedPatient) return;

    setIsSaving(true);
    try {
      const croppedImage =
        completedCrop && imgRef.current
          ? getCroppedDataUrl(imgRef.current, completedCrop)
          : screenshot;

      const response = await fetch(croppedImage);
      const blob = await response.blob();
      const safeName =
        fileName.trim().replace(/[/\\?%*:|"<>]/g, "-") || `screenshot_${Date.now()}`;
      const file = new File([blob], `${safeName}.png`, { type: "image/png" });

      const patientName =
        selectedPatient.firstName && selectedPatient.lastName
          ? `${selectedPatient.firstName} ${selectedPatient.lastName}`
          : selectedPatient.firstName ?? `patient-${selectedPatient.id}`;

      const formData = new FormData();
      formData.append("patientId", String(selectedPatient.id));
      formData.append("patientName", patientName);
      formData.append("files", file);

      await apiRequest("POST", "/api/claims/upload-to-cloud", formData);

      toast({
        title: "Saved",
        description: `Screenshot saved to ${patientName}'s attachments.`,
      });
      setScreenshot(null);
      setFileName("");
      setCrop(undefined);
      setCompletedCrop(undefined);
    } catch (error) {
      console.error("Error saving screenshot:", error);
      toast({
        title: "Error",
        description: "Failed to save screenshot to patient attachments.",
        variant: "destructive",
      });
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <div className="container mx-auto space-y-6">

      {/* Hero */}
      <div className="text-center space-y-3">
        <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-violet-100 mb-2">
          <Copy className="h-8 w-8 text-violet-600" />
        </div>
        <h1 className="text-3xl font-bold tracking-tight">Copy Agent</h1>
        <p className="text-muted-foreground text-base max-w-xl mx-auto">
          An AI agent reads and copies data including images and brings them to this app
          automatically. No manual input required.
        </p>
      </div>

      {/* Screenshot capture */}
      <Card>
        <CardHeader>
          <CardTitle>Capture Screenshot</CardTitle>
          <CardDescription>
            Capture your screen and save it to a patient's attachments.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          {screenshot ? (
            <div className="space-y-4">
              <ReactCrop
                crop={crop}
                onChange={(_, percentCrop) => setCrop(percentCrop)}
                onComplete={(pixelCrop) => setCompletedCrop(pixelCrop)}
              >
                <img
                  src={screenshot}
                  alt="Captured screenshot"
                  onLoad={handleImageLoad}
                  className="w-full rounded-lg border object-contain max-h-96"
                />
              </ReactCrop>
              <p className="text-xs text-muted-foreground">
                Drag the corners to crop, or leave as-is to save the full screenshot.
              </p>
              <div className="space-y-1.5 max-w-sm">
                <Label htmlFor="screenshot-filename">File name</Label>
                <div className="flex items-center gap-1">
                  <Input
                    id="screenshot-filename"
                    value={fileName}
                    onChange={(e) => setFileName(e.target.value)}
                    placeholder="screenshot"
                  />
                  <span className="text-sm text-muted-foreground">.png</span>
                </div>
              </div>
              <div className="flex flex-wrap gap-3">
                <Button variant="outline" onClick={handleRetake} disabled={isCapturing || isSaving}>
                  <RotateCcw className="h-4 w-4 mr-2" />
                  Retake
                </Button>
                <Button
                  onClick={handleSave}
                  disabled={!selectedPatient || isSaving}
                  title={!selectedPatient ? "Select a patient below first" : undefined}
                >
                  <Save className="h-4 w-4 mr-2" />
                  {isSaving ? "Saving..." : "Save to Patient"}
                </Button>
              </div>
              {!selectedPatient && (
                <p className="text-xs text-muted-foreground">
                  Select a patient below to enable saving.
                </p>
              )}
            </div>
          ) : (
            <Button onClick={handleCapture} disabled={isCapturing}>
              <Camera className="h-4 w-4 mr-2" />
              {countdown !== null
                ? `Capturing in ${countdown}...`
                : isCapturing
                ? "Waiting for screen share..."
                : "Take Screenshot"}
            </Button>
          )}
        </CardContent>
      </Card>

      {/* Patient search */}
      <Card>
        <CardHeader>
          <CardTitle>Patient Records</CardTitle>
          <CardDescription>
            Select the patient this screenshot belongs to.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <PatientTable
            allowCheckbox={true}
            onSelectPatient={setSelectedPatient}
          />
        </CardContent>
      </Card>

    </div>
  );
}
