import React, { useState, useEffect } from "react";
import { Eye, EyeOff } from "lucide-react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { useParams } from "wouter";
import { StaffTable } from "@/components/staffs/staff-table";
import { useToast } from "@/hooks/use-toast";
import { Card, CardContent } from "@/components/ui/card";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { StaffForm } from "@/components/staffs/staff-form";
import { DeleteConfirmationDialog } from "@/components/ui/deleteDialog";
import { CredentialTable } from "@/components/settings/insuranceCredTable";
import { useAuth } from "@/hooks/use-auth";
import { Staff } from "@repo/db/types";
import { NpiProviderTable } from "@/components/settings/npiProviderTable";
import { ProgramBridgeTable } from "@/components/settings/program-bridge-table";
import { TwilioSettingsCard } from "@/components/settings/twilio-settings-card";
import { AiSettingsCard } from "@/components/settings/ai-settings-card";

type SectionId =
  | "staff"
  | "users"
  | "account"
  | "credentials"
  | "npi"
  | "programs"
  | "twilio"
  | "ai";

export default function SettingsPage() {
  const { toast } = useToast();
  const { user: currentUser } = useAuth();
  const isAdmin = currentUser?.username === "admin";

  const params = useParams<{ section?: string }>();
  const section = (params.section as SectionId | undefined) ?? "staff";

  // Staff state
  const [modalOpen, setModalOpen] = useState(false);
  const [editingStaff, setEditingStaff] = useState<Staff | null>(null);
  const [isDeleteStaffOpen, setIsDeleteStaffOpen] = useState(false);
  const [currentStaff, setCurrentStaff] = useState<Staff | undefined>(undefined);

  // User management state
  const [newUsername, setNewUsername] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [showNewUserPassword, setShowNewUserPassword] = useState(false);
  const [showAdminPassword, setShowAdminPassword] = useState(false);
  const [usernameUser, setUsernameUser] = useState("");

  useEffect(() => {
    if (currentUser?.username) setUsernameUser(currentUser.username);
  }, [currentUser]);

  // ── Staff ──────────────────────────────────────────────────────
  const { data: staff = [], isLoading: staffLoading, isError: staffError, error: staffErrorMsg } = useQuery<Staff[]>({
    queryKey: ["/api/staffs/"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/api/staffs/");
      if (!res.ok) throw new Error("Failed to fetch staff");
      return res.json();
    },
    staleTime: 1000 * 60 * 5,
  });

  const addStaffMutate = useMutation<Staff, Error, Omit<Staff, "id" | "userId" | "createdAt">>({
    mutationFn: async (newStaff) => {
      const res = await apiRequest("POST", "/api/staffs/", newStaff);
      if (!res.ok) { const e = await res.json().catch(() => null); throw new Error(e?.message || "Failed to add staff"); }
      return res.json();
    },
    onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/staffs/"] }); toast({ title: "Staff Added" }); },
    onError: (e: any) => toast({ title: "Error", description: e?.message, variant: "destructive" }),
  });

  const updateStaffMutate = useMutation<Staff, Error, { id: number; updatedFields: Partial<Staff> }>({
    mutationFn: async ({ id, updatedFields }) => {
      const res = await apiRequest("PUT", `/api/staffs/${id}`, updatedFields);
      if (!res.ok) { const e = await res.json().catch(() => null); throw new Error(e?.message || "Failed to update staff"); }
      return res.json();
    },
    onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/staffs/"] }); toast({ title: "Staff Updated" }); },
    onError: (e: any) => toast({ title: "Error", description: e?.message, variant: "destructive" }),
  });

  const deleteStaffMutation = useMutation<number, Error, number>({
    mutationFn: async (id) => {
      const res = await apiRequest("DELETE", `/api/staffs/${id}`);
      if (!res.ok) { const e = await res.json().catch(() => null); throw new Error(e?.message || "Failed to delete staff"); }
      return id;
    },
    onSuccess: () => { setIsDeleteStaffOpen(false); queryClient.invalidateQueries({ queryKey: ["/api/staffs/"] }); toast({ title: "Staff Removed" }); },
    onError: (e: any) => toast({ title: "Error", description: e?.message, variant: "destructive" }),
  });

  useEffect(() => {
    if (addStaffMutate.status === "success" || updateStaffMutate.status === "success") setModalOpen(false);
  }, [addStaffMutate.status, updateStaffMutate.status]);

  // ── Users ──────────────────────────────────────────────────────
  const { data: allUsers = [], refetch: refetchUsers } = useQuery<{ id: number; username: string }[]>({
    queryKey: ["/api/users/list"],
    queryFn: async () => { const res = await apiRequest("GET", "/api/users/list"); if (!res.ok) return []; return res.json(); },
    enabled: false,
  });

  useEffect(() => { if (isAdmin) refetchUsers(); }, [isAdmin]);

  const addUserMutation = useMutation({
    mutationFn: async (data: { username: string; password: string }) => {
      const res = await apiRequest("POST", "/api/users/", data);
      if (!res.ok) { const e = await res.json().catch(() => null); throw new Error(e?.error || "Failed to create user"); }
      return res.json();
    },
    onSuccess: () => { setNewUsername(""); setNewPassword(""); refetchUsers(); toast({ title: "User Created" }); },
    onError: (e: any) => toast({ title: "Error", description: e?.message, variant: "destructive" }),
  });

  const deleteUserMutation = useMutation({
    mutationFn: async (id: number) => { const res = await apiRequest("DELETE", `/api/users/${id}`); if (!res.ok) throw new Error("Failed to delete user"); },
    onSuccess: () => { refetchUsers(); toast({ title: "User Deleted" }); },
    onError: (e: any) => toast({ title: "Error", description: e?.message, variant: "destructive" }),
  });

  const updateUserMutate = useMutation({
    mutationFn: async (updates: Partial<{ username: string; password: string }>) => {
      if (!currentUser?.id) throw new Error("User not loaded");
      const res = await apiRequest("PUT", `/api/users/${currentUser.id}`, updates);
      if (!res.ok) { const e = await res.json().catch(() => null); throw new Error(e?.error || "Failed to update user"); }
      return res.json();
    },
    onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/users/"] }); toast({ title: "Updated", description: "Your profile has been updated." }); },
    onError: (e: any) => toast({ title: "Error", description: e?.message, variant: "destructive" }),
  });

  // ── Section renderer ───────────────────────────────────────────
  const renderSection = () => {
    switch (section) {
      case "staff":
        return (
          <Card>
            <CardContent>
              <div className="mt-4">
                <StaffTable
                  staff={staff}
                  isLoading={staffLoading}
                  isError={staffError}
                  onAdd={() => { setEditingStaff(null); setModalOpen(true); }}
                  onEdit={(s) => { setEditingStaff(s); setModalOpen(true); }}
                  onDelete={(s) => { setCurrentStaff(s); setIsDeleteStaffOpen(true); }}
                  onView={(s) => alert(`Viewing staff member:\n${s.name} (${s.email || "No email"})`)}
                />
                {staffError && <p className="mt-4 text-red-600">{(staffErrorMsg as Error)?.message || "Failed to load staff data."}</p>}
                <DeleteConfirmationDialog
                  isOpen={isDeleteStaffOpen}
                  onConfirm={() => { if (currentStaff?.id) deleteStaffMutation.mutate(currentStaff.id); }}
                  onCancel={() => setIsDeleteStaffOpen(false)}
                  entityName={currentStaff?.name}
                />
              </div>
            </CardContent>
          </Card>
        );

      case "users":
        return (
          <Card>
            <CardContent className="space-y-4 py-6">
              <h3 className="text-lg font-semibold">Manage Users</h3>
              <div className="border rounded divide-y">
                {allUsers.length === 0 && <p className="text-sm text-gray-500 p-3">No users found.</p>}
                {allUsers.map((u) => (
                  <div key={u.id} className="flex items-center justify-between px-3 py-2">
                    <span className="text-sm font-medium">{u.username}</span>
                    {u.username !== "admin" && (
                      <button className="text-sm text-red-600 hover:underline" onClick={() => deleteUserMutation.mutate(u.id)} disabled={deleteUserMutation.isPending}>
                        Delete
                      </button>
                    )}
                  </div>
                ))}
              </div>
              <form className="space-y-3 pt-2" onSubmit={(e) => { e.preventDefault(); if (!newUsername.trim() || !newPassword.trim()) return; addUserMutation.mutate({ username: newUsername.trim(), password: newPassword.trim() }); }}>
                <h4 className="text-sm font-semibold text-gray-700">Add New User</h4>
                <div>
                  <label className="block text-sm font-medium">Username</label>
                  <input type="text" value={newUsername} onChange={(e) => setNewUsername(e.target.value)} className="mt-1 p-2 border rounded w-full" placeholder="Enter username" required />
                </div>
                <div>
                  <label className="block text-sm font-medium">Password</label>
                  <div className="relative mt-1">
                    <input type={showNewUserPassword ? "text" : "password"} value={newPassword} onChange={(e) => setNewPassword(e.target.value)} className="p-2 border rounded w-full pr-10" placeholder="••••••••" required />
                    <button type="button" onClick={() => setShowNewUserPassword((v) => !v)} className="absolute inset-y-0 right-2 flex items-center text-gray-500 hover:text-gray-700" tabIndex={-1}>
                      {showNewUserPassword ? <EyeOff size={16} /> : <Eye size={16} />}
                    </button>
                  </div>
                </div>
                <button type="submit" className="bg-teal-600 text-white px-4 py-2 rounded hover:bg-teal-700" disabled={addUserMutation.isPending}>
                  {addUserMutation.isPending ? "Adding..." : "Add User"}
                </button>
              </form>
            </CardContent>
          </Card>
        );

      case "account":
        return (
          <Card>
            <CardContent className="space-y-4 py-6">
              <h3 className="text-lg font-semibold">Account Settings</h3>
              <form className="space-y-4" onSubmit={(e) => {
                e.preventDefault();
                const formData = new FormData(e.currentTarget);
                const password = formData.get("password")?.toString().trim() || undefined;
                updateUserMutate.mutate({ ...(isAdmin ? {} : { username: usernameUser?.trim() || undefined }), password: password || undefined });
              }}>
                <div>
                  <label className="block text-sm font-medium">Username</label>
                  <input type="text" name="username" value={usernameUser} onChange={(e) => setUsernameUser(e.target.value)} className="mt-1 p-2 border rounded w-full disabled:bg-gray-100 disabled:cursor-not-allowed disabled:text-gray-500" disabled={isAdmin} />
                  {isAdmin && <p className="text-xs text-gray-500 mt-1">Admin username cannot be changed.</p>}
                </div>
                <div>
                  <label className="block text-sm font-medium">New Password</label>
                  <div className="relative mt-1">
                    <input type={showAdminPassword ? "text" : "password"} name="password" className="p-2 border rounded w-full pr-10" placeholder="••••••••" />
                    <button type="button" onClick={() => setShowAdminPassword((v) => !v)} className="absolute inset-y-0 right-2 flex items-center text-gray-500 hover:text-gray-700" tabIndex={-1}>
                      {showAdminPassword ? <EyeOff size={16} /> : <Eye size={16} />}
                    </button>
                  </div>
                  <p className="text-xs text-gray-500 mt-1">Leave blank to keep current password.</p>
                </div>
                <button type="submit" className="bg-teal-600 text-white px-4 py-2 rounded hover:bg-teal-700" disabled={updateUserMutate.isPending}>
                  {updateUserMutate.isPending ? "Saving..." : "Save Changes"}
                </button>
              </form>
            </CardContent>
          </Card>
        );

      case "credentials":
        return <CredentialTable />;

      case "npi":
        return <NpiProviderTable />;

      case "programs":
        return <ProgramBridgeTable />;

      case "twilio":
        return <TwilioSettingsCard />;

      case "ai":
        return <AiSettingsCard />;

      default:
        return null;
    }
  };

  return (
    <>
      {renderSection()}

      {/* Staff add/edit modal */}
      {modalOpen && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50">
          <div className="bg-white rounded-lg p-6 w-full max-w-md shadow-lg">
            <h2 className="text-lg font-bold mb-4">{editingStaff ? "Edit Staff" : "Add Staff"}</h2>
            <StaffForm
              initialData={editingStaff || undefined}
              onSubmit={(formData) => {
                if (editingStaff) {
                  if (!editingStaff.id) return;
                  updateStaffMutate.mutate({ id: editingStaff.id, updatedFields: formData });
                } else {
                  addStaffMutate.mutate(formData);
                }
              }}
              onCancel={() => setModalOpen(false)}
              isLoading={addStaffMutate.status === "pending" || updateStaffMutate.status === "pending"}
            />
          </div>
        </div>
      )}
    </>
  );
}
