import { useState, useMemo, useRef } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { TopAppBar } from "@/components/layout/top-app-bar";
import { Sidebar } from "@/components/layout/sidebar";
import { PatientTable } from "@/components/patients/patient-table";
import { AddPatientModal } from "@/components/patients/add-patient-modal";
import { FileUploadZone } from "@/components/file-upload/file-upload-zone";
import { Button } from "@/components/ui/button";
import { Plus, RefreshCw, File, FilePlus } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { PatientUncheckedCreateInputObjectSchema } from "@repo/db/usedSchemas";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useAuth } from "@/hooks/use-auth";
import { z } from "zod";
import useExtractPdfData from "@/hooks/use-extractPdfData";
import { useLocation } from "wouter";

const PatientSchema = (
  PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
).omit({
  appointments: true,
});
type Patient = z.infer<typeof PatientSchema>;

const insertPatientSchema = (
  PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
).omit({
  id: true,
  createdAt: true,
  userId: true,
});
type InsertPatient = z.infer<typeof insertPatientSchema>;

// Type for the ref to access modal methods
type AddPatientModalRef = {
  shouldSchedule: boolean;
  navigateToSchedule: (patientId: number) => void;
};

export default function PatientsPage() {
  const { toast } = useToast();
  const { user } = useAuth();
  const [isAddPatientOpen, setIsAddPatientOpen] = useState(false);
  const [currentPatient, setCurrentPatient] = useState<Patient | undefined>(
    undefined
  );
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
  const addPatientModalRef = useRef<AddPatientModalRef | null>(null);

  // File upload states
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
  const [isUploading, setIsUploading] = useState(false);
  const [isExtracting, setIsExtracting] = useState(false);
  const { mutate: extractPdf } = useExtractPdfData();
  const [location, navigate] = useLocation();

  // Add patient mutation
  const addPatientMutation = useMutation({
    mutationFn: async (patient: InsertPatient) => {
      const res = await apiRequest("POST", "/api/patients/", patient);
      return res.json();
    },
    onSuccess: (newPatient) => {
      setIsAddPatientOpen(false);
      queryClient.invalidateQueries({ queryKey: ["/api/patients/"] });
      toast({
        title: "Success",
        description: "Patient added successfully!",
        variant: "default",
      });

      // If the add patient modal wants to proceed to scheduling, redirect to appointments page
      if (addPatientModalRef.current?.shouldSchedule) {
        addPatientModalRef.current.navigateToSchedule(newPatient.id);
      }
    },
    onError: (error) => {
      toast({
        title: "Error",
        description: `Failed to add patient: ${error.message}`,
        variant: "destructive",
      });
    },
  });

  const toggleMobileMenu = () => {
    setIsMobileMenuOpen(!isMobileMenuOpen);
  };

  const handleAddPatient = (patient: InsertPatient) => {
    if (user) {
      addPatientMutation.mutate({
        ...patient,
        userId: user.id,
      });
    }
  };

  const isLoading = addPatientMutation.isPending;


  // File upload handling
  const handleFileUpload = (file: File) => {
    setIsUploading(true);
    setUploadedFile(file);

    toast({
      title: "File Selected",
      description: `${file.name} is ready for processing.`,
      variant: "default",
    });

    setIsUploading(false);
  };

  // data extraction
  const handleExtract = () => {
    setIsExtracting(true);

    if (!uploadedFile) {
      return toast({
        title: "Error",
        description: "Please upload a PDF",
        variant: "destructive",
      });
    }
    extractPdf(uploadedFile, {
      onSuccess: (data) => {
        setIsExtracting(false);

        toast({
          title: "Success Pdf Data Extracted",
          description: `Name: ${data.name}, Member ID: ${data.memberId}, DOB: ${data.dob}`,
          variant: "default",
        });

        const params = new URLSearchParams({
          name: data.name,
          memberId: data.memberId,
          dob: data.dob,
        });

        navigate(
          `/claims?name=${encodeURIComponent(data.name)}&memberId=${data.memberId}&dob=${data.dob}`
        );
      },
    });
  };

  return (
    <div className="flex h-screen overflow-hidden bg-gray-100">
      <Sidebar
        isMobileOpen={isMobileMenuOpen}
        setIsMobileOpen={setIsMobileMenuOpen}
      />

      <div className="flex-1 flex flex-col overflow-hidden">
        <TopAppBar toggleMobileMenu={toggleMobileMenu} />

        <main className="flex-1 overflow-y-auto p-4">
          <div className="container mx-auto space-y-6">
            <div className="flex justify-between items-center">
              <div>
                <h1 className="text-3xl font-bold tracking-tight">Patients</h1>
                <p className="text-muted-foreground">
                  Manage patient records and information
                </p>
              </div>
              <div className="flex space-x-2">
                <Button
                  onClick={() => {
                    setCurrentPatient(undefined);
                    setIsAddPatientOpen(true);
                  }}
                  className="gap-1"
                  disabled={isLoading}
                >
                  <Plus className="h-4 w-4" />
                  New Patient
                </Button>
              </div>
            </div>

            {/* File Upload Zone */}
            <div className="grid gap-4 md:grid-cols-4">
              <div className="md:col-span-3">
                <Card>
                  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
                    <CardTitle className="text-sm font-medium">
                      Upload Patient Document
                    </CardTitle>
                    <File className="h-4 w-4 text-muted-foreground" />
                  </CardHeader>
                  <CardContent>
                    <FileUploadZone
                      onFileUpload={handleFileUpload}
                      isUploading={isUploading}
                      acceptedFileTypes="application/pdf"
                    />
                  </CardContent>
                </Card>
              </div>
              <div className="md:col-span-1 flex items-end">
                <Button
                  className="w-full h-12 gap-2"
                  disabled={!uploadedFile || isExtracting}
                  onClick={handleExtract}
                >
                  {isExtracting ? (
                    <>
                      <RefreshCw className="h-4 w-4 animate-spin" />
                      Processing...
                    </>
                  ) : (
                    <>
                      <FilePlus className="h-4 w-4" />
                      Extract Info And Claim
                    </>
                  )}
                </Button>
              </div>
            </div>

            {/* Patients Table */}
            <Card>
              <CardHeader>
                <CardTitle>Patient Records</CardTitle>
                <CardDescription>
                  View and manage all patient information
                </CardDescription>
              </CardHeader>
              <CardContent>
                <PatientTable
                  allowDelete={true}
                  allowEdit={true}
                  allowView={true}
                />
              </CardContent>
            </Card>

            {/* Add/Edit Patient Modal */}
            <AddPatientModal
              ref={addPatientModalRef}
              open={isAddPatientOpen}
              onOpenChange={setIsAddPatientOpen}
              onSubmit={handleAddPatient}
              isLoading={isLoading}
              patient={currentPatient}
            />
          </div>
        </main>
      </div>
    </div>
  );
}
