import { useState, ReactNode } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { toast } from "sonner";
import { Plus, Pencil, Trash2, Building2, X, CalendarDays } from "lucide-react";
import TrainerAvailabilityPanel from "@/components/admin/TrainerAvailabilityPanel";
import AdminLayout from "@/layouts/AdminLayout";
import { useAuth } from "@/hooks/useAuth";

interface Trainer {
  id: string;
  first_name: string;
  last_name: string;
  email: string | null;
  phone: string | null;
  notes: string | null;
}

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

const emptyForm = { first_name: "", last_name: "", email: "", phone: "", notes: "", company_id: "" };

const TrainersPage = () => {
  const queryClient = useQueryClient();
  // Company managers manage only their own trainers (backend-enforced); they
  // don't pick a company — their trainers are auto-linked to their company.
  const { hasRole, isSysLevel } = useAuth();
  const isManager = hasRole("company_manager") && !isSysLevel();
  const [showForm, setShowForm] = useState(false);
  const [editingTrainer, setEditingTrainer] = useState<Trainer | null>(null);
  const [form, setForm] = useState(emptyForm);
  const [companyDialogOpen, setCompanyDialogOpen] = useState(false);
  const [selectedTrainerId, setSelectedTrainerId] = useState<string | null>(null);
  const [selectedCompanyId, setSelectedCompanyId] = useState("");
  const [availabilityTrainerId, setAvailabilityTrainerId] = useState<string | null>(null);

  const { data: trainers, isLoading } = useQuery({
    queryKey: ["trainers"],
    queryFn: async (): Promise<Trainer[]> => {
      const res = await fetch("/api/admin/trainers");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const { data: companies } = useQuery({
    queryKey: ["training_companies"],
    enabled: !isManager,
    queryFn: async (): Promise<any[]> => {
      const res = await fetch("/api/admin/training-companies");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const trainingCompanies = companies || [];

  const { data: trainerCompanies } = useQuery({
    queryKey: ["trainer_companies"],
    queryFn: async (): Promise<any[]> => {
      const res = await fetch("/api/admin/trainer-companies");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const saveMutation = useMutation({
    mutationFn: async (values: typeof form) => {
      const path = editingTrainer
        ? `/api/admin/trainers/${editingTrainer.id}`
        : `/api/admin/trainers`;
      const method = editingTrainer ? "PUT" : "POST";
      const res = await fetch(path, {
        method,
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify(values),
      });
      if (!res.ok) throw new Error("Failed to save trainer");
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["trainers"] });
      queryClient.invalidateQueries({ queryKey: ["trainers-count"] });
      queryClient.invalidateQueries({ queryKey: ["trainer_companies"] });
      toast.success(editingTrainer ? "Trainer updated" : "Trainer added");
      resetForm();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      const res = await fetch(`/api/admin/trainers/${id}`, {
        method: "DELETE",
        headers: { "X-CSRF-TOKEN": csrfToken() },
      });
      if (!res.ok) throw new Error("Failed to delete trainer");
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["trainers"] });
      queryClient.invalidateQueries({ queryKey: ["trainers-count"] });
      toast.success("Trainer deleted");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const assignCompanyMutation = useMutation({
    mutationFn: async ({ trainer_id, company_id }: { trainer_id: string; company_id: string }) => {
      const res = await fetch(`/api/admin/trainer-companies`, {
        method: "POST",
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify({ trainer_id, company_id }),
      });
      if (!res.ok) throw new Error("Failed to assign company");
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["trainer_companies"] });
      toast.success("Company assigned");
      setCompanyDialogOpen(false);
      setSelectedCompanyId("");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const removeCompanyMutation = useMutation({
    mutationFn: async (id: string) => {
      const res = await fetch(`/api/admin/trainer-companies/${id}`, {
        method: "DELETE",
        headers: { "X-CSRF-TOKEN": csrfToken() },
      });
      if (!res.ok) throw new Error("Failed to remove company");
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["trainer_companies"] });
      toast.success("Company removed");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const resetForm = () => {
    setForm(emptyForm);
    setEditingTrainer(null);
    setShowForm(false);
  };

  const openEdit = (t: Trainer) => {
    setEditingTrainer(t);
    const currentCompany = trainerCompanies?.find((tc) => tc.trainer_id === t.id);
    setForm({
      first_name: t.first_name,
      last_name: t.last_name,
      email: t.email || "",
      phone: t.phone || "",
      notes: t.notes || "",
      company_id: currentCompany?.company_id || "",
    });
    setShowForm(true);
  };

  const getTrainerCompanies = (trainerId: string) =>
    trainerCompanies?.filter((tc) => tc.trainer_id === trainerId) || [];

  const availabilityTrainer = trainers?.find((t) => t.id === availabilityTrainerId);

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <h1 className="text-2xl font-bold text-foreground">Trainers</h1>
        <Button variant="hero" onClick={() => { setEditingTrainer(null); setForm(emptyForm); setShowForm(true); }}>
          <Plus className="mr-2 h-4 w-4" /> Add Trainer
        </Button>
      </div>

      {showForm && (
        <Card className="mb-6">
          <CardHeader className="flex flex-row items-center justify-between pb-2">
            <CardTitle>{editingTrainer ? "Edit Trainer" : "Add Trainer"}</CardTitle>
            <Button variant="ghost" size="sm" onClick={resetForm}><X className="h-4 w-4" /></Button>
          </CardHeader>
          <CardContent>
            <form onSubmit={(e) => { e.preventDefault(); saveMutation.mutate(form); }} className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label>First Name</Label>
                  <Input value={form.first_name} onChange={(e) => setForm((f) => ({ ...f, first_name: e.target.value }))} required />
                </div>
                <div className="space-y-2">
                  <Label>Last Name</Label>
                  <Input value={form.last_name} onChange={(e) => setForm((f) => ({ ...f, last_name: e.target.value }))} required />
                </div>
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label>Email</Label>
                  <Input type="email" value={form.email} onChange={(e) => setForm((f) => ({ ...f, email: e.target.value }))} />
                </div>
                <div className="space-y-2">
                  <Label>Phone</Label>
                  <Input value={form.phone} onChange={(e) => setForm((f) => ({ ...f, phone: e.target.value }))} />
                </div>
              </div>
              {!isManager && (
                <div className="space-y-2">
                  <Label>Company</Label>
                  <Select value={form.company_id} onValueChange={(v) => setForm((f) => ({ ...f, company_id: v }))}>
                    <SelectTrigger><SelectValue placeholder="Select a company" /></SelectTrigger>
                    <SelectContent>
                      {trainingCompanies.map((c) => (
                        <SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              )}
              <div className="space-y-2">
                <Label>Notes</Label>
                <Textarea value={form.notes} onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))} />
              </div>
              <div className="flex gap-2">
                <Button type="submit" variant="hero" disabled={saveMutation.isPending}>
                  {saveMutation.isPending ? "Saving..." : "Save"}
                </Button>
                <Button type="button" variant="outline" onClick={resetForm}>Cancel</Button>
              </div>
            </form>
          </CardContent>
        </Card>
      )}

      {/* Company assignment dialog */}
      <Dialog open={companyDialogOpen} onOpenChange={setCompanyDialogOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>Assign Company</DialogTitle></DialogHeader>
          <div className="space-y-4">
            <Select value={selectedCompanyId} onValueChange={setSelectedCompanyId}>
              <SelectTrigger><SelectValue placeholder="Select a company" /></SelectTrigger>
              <SelectContent>
                {trainingCompanies.map((c) => (
                  <SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Button variant="hero" className="w-full" disabled={!selectedCompanyId} onClick={() => {
              if (selectedTrainerId && selectedCompanyId) assignCompanyMutation.mutate({ trainer_id: selectedTrainerId, company_id: selectedCompanyId });
            }}>Assign</Button>

            {selectedTrainerId && (
              <div className="border-t border-border pt-4">
                <p className="text-sm font-medium text-foreground mb-2">Current Companies:</p>
                {getTrainerCompanies(selectedTrainerId).length === 0 ? (
                  <p className="text-sm text-muted-foreground">None assigned</p>
                ) : (
                  <div className="space-y-2">
                    {getTrainerCompanies(selectedTrainerId).map((tc: any) => (
                      <div key={tc.id} className="flex items-center justify-between bg-secondary rounded-lg px-3 py-2">
                        <span className="text-sm text-foreground">{tc.training_companies?.name}</span>
                        <Button variant="ghost" size="sm" onClick={() => removeCompanyMutation.mutate(tc.id)}>
                          <Trash2 className="h-3 w-3 text-destructive" />
                        </Button>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}
          </div>
        </DialogContent>
      </Dialog>

      {isLoading ? (
        <p className="text-muted-foreground">Loading trainers...</p>
      ) : (
        <div className="bg-card border border-border rounded-xl overflow-hidden">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Name</TableHead>
                <TableHead>Email</TableHead>
                <TableHead>Phone</TableHead>
                <TableHead>Companies</TableHead>
                <TableHead className="w-[150px]">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {trainers?.map((t) => (
                <TableRow key={t.id} className={availabilityTrainerId === t.id ? "bg-primary/5" : ""}>
                  <TableCell className="font-medium">{t.first_name} {t.last_name}</TableCell>
                  <TableCell>{t.email || "—"}</TableCell>
                  <TableCell>{t.phone || "—"}</TableCell>
                  <TableCell>
                    {getTrainerCompanies(t.id).map((tc: any) => tc.training_companies?.name).join(", ") || "—"}
                  </TableCell>
                  <TableCell>
                    <div className="flex gap-1">
                      <Button variant="ghost" size="sm" onClick={() => openEdit(t)}>
                        <Pencil className="h-3 w-3" />
                      </Button>
                      {!isManager && (
                        <Button variant="ghost" size="sm" title="Assign company" onClick={() => { setSelectedTrainerId(t.id); setCompanyDialogOpen(true); }}>
                          <Building2 className="h-3 w-3" />
                        </Button>
                      )}
                      <Button
                        variant={availabilityTrainerId === t.id ? "default" : "ghost"}
                        size="sm"
                        onClick={() => setAvailabilityTrainerId(availabilityTrainerId === t.id ? null : t.id)}
                      >
                        <CalendarDays className="h-3 w-3" />
                      </Button>
                      <Button variant="ghost" size="sm" onClick={() => deleteMutation.mutate(t.id)}>
                        <Trash2 className="h-3 w-3 text-destructive" />
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))}
              {trainers?.length === 0 && (
                <TableRow>
                  <TableCell colSpan={5} className="text-center text-muted-foreground py-8">No trainers yet. Add one to get started.</TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      )}

      {/* Inline Availability Panel */}
      {availabilityTrainerId && availabilityTrainer && (
        <div className="mt-6">
          <TrainerAvailabilityPanel
            trainerId={availabilityTrainerId}
            trainerName={`${availabilityTrainer.first_name} ${availabilityTrainer.last_name}`}
          />
        </div>
      )}
    </div>
  );
};

TrainersPage.layout = (page: ReactNode) => <AdminLayout>{page}</AdminLayout>;

export default TrainersPage;
