import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { toast } from "sonner";
import { Building2, Users, ClipboardList, Loader2 } from "lucide-react";
import { AppShell } from "@/components/AppShell";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/lib/use-auth";
import { addCompanyStaff } from "@/lib/staff.functions";
import type { Database, TablesUpdate } from "@/integrations/supabase/types";

type BookingStatus = Database["public"]["Enums"]["booking_status"];
type CompanyRole = Database["public"]["Enums"]["company_role"];

const statuses: BookingStatus[] = [
  "requested",
  "confirmed",
  "inspector_assigned",
  "inspection_completed",
  "treatment_scheduled",
  "completed",
  "cancelled",
];
const roles: CompanyRole[] = ["company_admin", "inspector", "technician", "agent"];

export const Route = createFileRoute("/_authenticated/provider")({
  head: () => ({
    meta: [
      { title: "Service Provider Portal | Emma Mold Inspection Services" },
      {
        name: "description",
        content: "Manage your company profile, staff, assigned jobs and inspection reports as an approved service provider.",
      },
      { property: "og:title", content: "Service Provider Portal" },
      { property: "og:description", content: "Company profile, staff, bookings and reports for mold service providers." },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary_large_image" },
    ],
  }),
  component: ProviderPortal,
});

const tabs = ["Company", "Staff", "Jobs"] as const;
type Tab = (typeof tabs)[number];

function ProviderPortal() {
  const { user, companyId, isCompanyAdmin, loading } = useAuth();
  const [tab, setTab] = useState<Tab>("Company");

  const company = useQuery({
    queryKey: ["provider-company-status", companyId],
    enabled: Boolean(companyId),
    queryFn: async () => {
      const { data, error } = await supabase.from("companies").select("name,status").eq("id", companyId!).maybeSingle();
      if (error) throw error;
      return data;
    },
  });

  if (loading) return <AppShell>Loading…</AppShell>;
  if (!companyId) return <AppShell>{user ? <RegisterCompany /> : null}</AppShell>;
  if (company.isLoading) return <AppShell>Loading…</AppShell>;
  if (company.data && company.data.status !== "approved")
    return (
      <AppShell>
        <div className="rounded-3xl border border-border/60 bg-card p-6 text-center shadow-card">
          <Building2 className="mx-auto h-8 w-8 text-primary" />
          <h1 className="mt-3 text-xl font-bold">
            {company.data.status === "pending" ? "Pending Admin Approval" : `Application ${company.data.status}`}
          </h1>
          <p className="mt-2 text-sm text-muted-foreground">
            {company.data.status === "pending"
              ? `${company.data.name} is being reviewed by Emma Exclusive Teams. You'll be notified once approved, then the full provider portal unlocks.`
              : "Your company cannot access the provider portal. Contact Emma Exclusive Teams for details."}
          </p>
        </div>
      </AppShell>
    );

  return (
    <AppShell>
      <h1 className="text-2xl font-bold">Service Provider Portal</h1>
      <div className="mt-4 flex flex-wrap gap-2">
        {tabs.map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`rounded-full px-4 py-2 text-xs font-semibold ${
              tab === t ? "bg-brand text-primary-foreground" : "bg-muted text-muted-foreground"
            }`}
          >
            {t}
          </button>
        ))}
      </div>
      {tab === "Company" ? <CompanyProfile companyId={companyId} canEdit={isCompanyAdmin} /> : null}
      {tab === "Staff" ? <StaffPanel companyId={companyId} canEdit={isCompanyAdmin} /> : null}
      {tab === "Jobs" ? <JobsPanel companyId={companyId} /> : null}
    </AppShell>
  );
}

function RegisterCompany() {
  const { user } = useAuth();
  const qc = useQueryClient();
  const [form, setForm] = useState({ name: "", phone: "", email: "", description: "", areas: "", services: "" });
  const [busy, setBusy] = useState(false);

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (!user) return;
    setBusy(true);
    const slug = `${form.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "")}-${Math.random()
      .toString(36)
      .slice(2, 6)}`;
    const { error } = await supabase.from("companies").insert({
      owner_id: user.id,
      name: form.name,
      slug,
      phone: form.phone || null,
      email: form.email || null,
      description: form.description || null,
      service_areas: form.areas ? form.areas.split(",").map((s) => s.trim()).filter(Boolean) : [],
      services_offered: form.services ? form.services.split(",").map((s) => s.trim()).filter(Boolean) : [],
    });
    setBusy(false);
    if (error) return toast.error(error.message);
    toast.success("Company submitted for approval by Emma Exclusive Teams.");
    qc.invalidateQueries();
    window.location.reload();
  }

  const input = "mt-1 w-full rounded-xl border border-input bg-background px-3 py-2.5 text-sm";

  return (
    <>
      <h1 className="flex items-center gap-2 text-2xl font-bold">
        <Building2 className="h-6 w-6 text-primary" /> Register your company
      </h1>
      <p className="mt-1 text-sm text-muted-foreground">
        Service providers join the Emma marketplace after approval. You will manage staff, jobs and reports here.
      </p>
      <form onSubmit={submit} className="mt-5 space-y-3 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
        <label className="block text-left text-xs font-medium text-muted-foreground">
          Company name
          <input required className={input} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
        </label>
        <label className="block text-left text-xs font-medium text-muted-foreground">
          Phone
          <input className={input} value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} />
        </label>
        <label className="block text-left text-xs font-medium text-muted-foreground">
          Email
          <input type="email" className={input} value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
        </label>
        <label className="block text-left text-xs font-medium text-muted-foreground">
          Service areas (comma separated)
          <input className={input} value={form.areas} onChange={(e) => setForm({ ...form, areas: e.target.value })} />
        </label>
        <label className="block text-left text-xs font-medium text-muted-foreground">
          Services offered (comma separated)
          <input className={input} value={form.services} onChange={(e) => setForm({ ...form, services: e.target.value })} />
        </label>
        <label className="block text-left text-xs font-medium text-muted-foreground">
          About the company
          <textarea rows={3} className={input} value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
        </label>
        <button
          disabled={busy}
          className="w-full rounded-2xl bg-brand py-3.5 text-sm font-semibold text-primary-foreground disabled:opacity-60"
        >
          {busy ? "Submitting…" : "Submit for approval"}
        </button>
      </form>
    </>
  );
}

function CompanyProfile({ companyId, canEdit }: { companyId: string; canEdit: boolean }) {
  const qc = useQueryClient();
  const { data } = useQuery({
    queryKey: ["company", companyId],
    queryFn: async () => {
      const { data, error } = await supabase.from("companies").select("*").eq("id", companyId).maybeSingle();
      if (error) throw error;
      return data;
    },
  });

  if (!data) return <p className="mt-4 text-sm text-muted-foreground">Loading company…</p>;

  async function save(patch: TablesUpdate<"companies">) {
    const { error } = await supabase.from("companies").update(patch).eq("id", companyId);
    if (error) return toast.error("Could not save.");
    toast.success("Company profile updated.");
    qc.invalidateQueries({ queryKey: ["company", companyId] });
  }

  const input = "mt-1 w-full rounded-xl border border-input bg-background px-3 py-2.5 text-sm";

  return (
    <div className="mt-4 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
      <div className="flex items-center justify-between gap-3">
        <h2 className="text-lg font-semibold">{data.name}</h2>
        <span className="rounded-full bg-muted px-3 py-1 text-[11px] font-semibold capitalize">{data.status}</span>
      </div>
      {data.status !== "approved" ? (
        <p className="mt-2 rounded-xl bg-warning/20 px-3 py-2 text-xs">
          Awaiting approval from Emma Exclusive Teams. Customers cannot book you yet.
        </p>
      ) : null}
      <div className="mt-4 space-y-3">
        <label className="block text-xs font-medium text-muted-foreground">
          Phone
          <input
            disabled={!canEdit}
            className={input}
            defaultValue={data.phone ?? ""}
            onBlur={(e) => e.target.value !== (data.phone ?? "") && save({ phone: e.target.value })}
          />
        </label>
        <label className="block text-xs font-medium text-muted-foreground">
          Email
          <input
            disabled={!canEdit}
            className={input}
            defaultValue={data.email ?? ""}
            onBlur={(e) => e.target.value !== (data.email ?? "") && save({ email: e.target.value })}
          />
        </label>
        <label className="block text-xs font-medium text-muted-foreground">
          Logo image URL
          <input
            disabled={!canEdit}
            className={input}
            defaultValue={data.logo_url ?? ""}
            onBlur={(e) => e.target.value !== (data.logo_url ?? "") && save({ logo_url: e.target.value })}
          />
        </label>
        <label className="block text-xs font-medium text-muted-foreground">
          Service areas (comma separated)
          <input
            disabled={!canEdit}
            className={input}
            defaultValue={(data.service_areas ?? []).join(", ")}
            onBlur={(e) =>
              save({ service_areas: e.target.value.split(",").map((s) => s.trim()).filter(Boolean) })
            }
          />
        </label>
        <label className="block text-xs font-medium text-muted-foreground">
          Services offered (comma separated)
          <input
            disabled={!canEdit}
            className={input}
            defaultValue={(data.services_offered ?? []).join(", ")}
            onBlur={(e) =>
              save({ services_offered: e.target.value.split(",").map((s) => s.trim()).filter(Boolean) })
            }
          />
        </label>
        <label className="block text-xs font-medium text-muted-foreground">
          About
          <textarea
            disabled={!canEdit}
            rows={3}
            className={input}
            defaultValue={data.description ?? ""}
            onBlur={(e) => e.target.value !== (data.description ?? "") && save({ description: e.target.value })}
          />
        </label>
      </div>
    </div>
  );
}

function StaffPanel({ companyId, canEdit }: { companyId: string; canEdit: boolean }) {
  const qc = useQueryClient();
  const addStaff = useServerFn(addCompanyStaff);
  const [email, setEmail] = useState("");
  const [role, setRole] = useState<CompanyRole>("inspector");
  const [busy, setBusy] = useState(false);

  const { data } = useQuery({
    queryKey: ["company-staff", companyId],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("company_members")
        .select("id,user_id,role,full_name,active")
        .eq("company_id", companyId)
        .order("created_at");
      if (error) throw error;
      return data;
    },
  });

  async function add(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    try {
      await addStaff({ data: { companyId, email, role } });
      toast.success("Team member added.");
      setEmail("");
      qc.invalidateQueries({ queryKey: ["company-staff", companyId] });
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not add that person.");
    } finally {
      setBusy(false);
    }
  }

  async function toggleActive(id: string, active: boolean) {
    const { error } = await supabase.from("company_members").update({ active }).eq("id", id);
    if (error) return toast.error("Could not update.");
    qc.invalidateQueries({ queryKey: ["company-staff", companyId] });
  }

  return (
    <div className="mt-4 space-y-3">
      {canEdit ? (
        <form onSubmit={add} className="rounded-3xl border border-border/60 bg-card p-4 shadow-card">
          <h2 className="flex items-center gap-2 text-sm font-semibold">
            <Users className="h-4 w-4 text-primary" /> Add a team member
          </h2>
          <p className="mt-1 text-[11px] text-muted-foreground">They must already have an Emma Mold account.</p>
          <input
            required
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="teammate@example.com"
            className="mt-3 w-full rounded-xl border border-input bg-background px-3 py-2.5 text-sm"
          />
          <select
            value={role}
            onChange={(e) => setRole(e.target.value as CompanyRole)}
            className="mt-2 w-full rounded-xl border border-input bg-background px-3 py-2.5 text-sm"
          >
            {roles.map((r) => (
              <option key={r} value={r}>
                {r.replaceAll("_", " ")}
              </option>
            ))}
          </select>
          <button
            disabled={busy}
            className="mt-3 flex w-full items-center justify-center gap-2 rounded-2xl bg-brand py-3 text-sm font-semibold text-primary-foreground disabled:opacity-60"
          >
            {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : null} Add to team
          </button>
        </form>
      ) : null}

      {data?.map((m) => (
        <article key={m.id} className="flex items-center justify-between gap-3 rounded-2xl border border-border/60 bg-card p-4 shadow-card">
          <div>
            <p className="text-sm font-semibold">{m.full_name ?? "Team member"}</p>
            <p className="text-[11px] text-muted-foreground capitalize">{m.role.replaceAll("_", " ")}</p>
          </div>
          {canEdit ? (
            <button
              onClick={() => toggleActive(m.id, !m.active)}
              className="rounded-xl border border-border px-3 py-2 text-[11px] font-semibold"
            >
              {m.active ? "Deactivate" : "Reactivate"}
            </button>
          ) : null}
        </article>
      ))}
    </div>
  );
}

function JobsPanel({ companyId }: { companyId: string }) {
  const qc = useQueryClient();
  const { data: staff } = useQuery({
    queryKey: ["company-staff", companyId],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("company_members")
        .select("user_id,full_name,role")
        .eq("company_id", companyId)
        .eq("active", true);
      if (error) throw error;
      return data;
    },
  });

  const { data: bookings } = useQuery({
    queryKey: ["company-bookings", companyId],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("bookings")
        .select("*")
        .eq("company_id", companyId)
        .order("created_at", { ascending: false });
      if (error) throw error;
      return data;
    },
  });

  async function update(id: string, patch: TablesUpdate<"bookings">) {
    const { error } = await supabase.from("bookings").update(patch).eq("id", id);
    if (error) return toast.error("Update failed.");
    toast.success("Job updated.");
    qc.invalidateQueries({ queryKey: ["company-bookings", companyId] });
  }

  return (
    <div className="mt-4 space-y-3">
      {bookings?.map((b) => (
        <article key={b.id} className="rounded-2xl border border-border/60 bg-card p-4 shadow-card">
          <h2 className="flex items-center gap-2 text-sm font-semibold">
            <ClipboardList className="h-4 w-4 text-primary" /> {b.service_name} — {b.full_name}
          </h2>
          <p className="mt-1 text-xs text-muted-foreground">
            {b.phone} • {b.address}
          </p>
          <p className="mt-1 text-xs text-muted-foreground">
            {b.preferred_date ?? "No date"} • {b.preferred_time}
          </p>
          <div className="mt-3 grid gap-2 sm:grid-cols-2">
            <select
              className="rounded-xl border border-input bg-background px-3 py-2 text-xs"
              value={b.status}
              onChange={(e) => update(b.id, { status: e.target.value as BookingStatus })}
            >
              {statuses.map((s) => (
                <option key={s} value={s}>
                  {s.replaceAll("_", " ")}
                </option>
              ))}
            </select>
            <select
              className="rounded-xl border border-input bg-background px-3 py-2 text-xs"
              value={b.assigned_to ?? ""}
              onChange={(e) => {
                const member = staff?.find((s) => s.user_id === e.target.value);
                update(b.id, {
                  assigned_to: e.target.value || null,
                  inspector_name: member?.full_name ?? null,
                });
              }}
            >
              <option value="">Unassigned</option>
              {staff?.map((s) => (
                <option key={s.user_id} value={s.user_id}>
                  {s.full_name ?? s.role}
                </option>
              ))}
            </select>
          </div>
        </article>
      ))}
      {!bookings?.length ? (
        <p className="rounded-2xl bg-muted p-4 text-sm text-muted-foreground">No jobs assigned to your company yet.</p>
      ) : null}
    </div>
  );
}