"use client";

import { useQuery } from "@tanstack/react-query";
import {
  PageHeader,
  DataTable,
  EmptyState,
  Badge,
} from "@/src/shared/ui";
import { healthcareApi } from "@/src/modules/healthcare/services/healthcare-api";
import { useHealthcareDoctorContext } from "@/src/modules/healthcare/hooks/useHealthcareDoctorContext";
import { useHealthcareLookups } from "@/src/modules/healthcare/hooks/useHealthcareLookups";
import {
  AppointmentCard,
  DoctorCard,
  PatientCard,
  PrescriptionCard,
  QueueRow,
  StatWidget,
} from "@/src/modules/healthcare/design-system";
import {
  AggregateStatsRow,
  AnalyticsPage,
  HealthcarePageError,
  HealthcarePageLoader,
  ServiceMetaBadges,
  SettingsListPage,
} from "./shared";
import { ErrorState } from "@/src/shared/ui";

function DoctorGate({ children }: { children: (ctx: ReturnType<typeof useHealthcareDoctorContext>) => React.ReactNode }) {
  const ctx = useHealthcareDoctorContext();
  if (ctx.isLoading) return <HealthcarePageLoader label="در حال بارگذاری پروفایل پزشک…" />;
  if (ctx.error) return <HealthcarePageError error={ctx.error} onRetry={() => ctx.refetch()} />;
  if (!ctx.tenantId || !ctx.doctorId) {
    return <ErrorState message="پروفایل پزشک برای این workspace یافت نشد." />;
  }
  return <>{children(ctx)}</>;
}

export function DoctorDashboard() {
  return (
    <DoctorGate>
      {(ctx) => (
        <DoctorDashboardInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} doctor={ctx.doctor!} />
      )}
    </DoctorGate>
  );
}

function DoctorDashboardInner({
  tenantId,
  doctorId,
  doctor,
}: {
  tenantId: string;
  doctorId: string;
  doctor: { display_name: string };
}) {
  const dashQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "dashboard"],
    queryFn: () => healthcareApi.doctorPanel.dashboard(tenantId, doctorId),
  });
  const { patientName } = useHealthcareLookups();

  if (dashQ.isLoading) return <HealthcarePageLoader />;
  if (dashQ.error) return <HealthcarePageError error={dashQ.error} onRetry={() => dashQ.refetch()} />;

  const d = dashQ.data!;

  return (
    <div>
      <PageHeader
        title={`داشبورد ${doctor.display_name}`}
        description="آمار امروز و نوبت‌های پیش‌رو از doctor-panel API."
        actions={<ServiceMetaBadges />}
      />
      <AggregateStatsRow
        stats={[
          { label: "صف", value: d.queued_count },
          { label: "در حال ویزیت", value: d.in_progress_count },
          { label: "تکمیل امروز", value: d.completed_today_count },
        ]}
      />
      <section className="mt-8 space-y-3">
        <h2 className="font-semibold text-secondary">نوبت‌های پیش‌رو</h2>
        {d.upcoming_appointments.length === 0 ? (
          <EmptyState title="نوبت پیش‌رویی نیست" />
        ) : (
          d.upcoming_appointments.map((a) => (
            <AppointmentCard
              key={a.id}
              appointment={a}
              doctorName={doctor.display_name}
            />
          ))
        )}
      </section>
    </div>
  );
}

export function DoctorScheduleToday() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorScheduleInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} today />}
    </DoctorGate>
  );
}

export function DoctorScheduleCalendar() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorScheduleInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} today={false} />}
    </DoctorGate>
  );
}

function DoctorScheduleInner({
  tenantId,
  doctorId,
  today,
}: {
  tenantId: string;
  doctorId: string;
  today: boolean;
}) {
  const apptsQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "appointments", today],
    queryFn: () =>
      healthcareApi.appointments.list(tenantId, { doctor_id: doctorId, page_size: 50 }),
  });
  const { patientName } = useHealthcareLookups();

  if (apptsQ.isLoading) return <HealthcarePageLoader />;
  if (apptsQ.error) return <HealthcarePageError error={apptsQ.error} onRetry={() => apptsQ.refetch()} />;

  const startOfDay = new Date();
  startOfDay.setHours(0, 0, 0, 0);
  const endOfDay = new Date();
  endOfDay.setHours(23, 59, 59, 999);

  const items = (apptsQ.data?.items ?? []).filter((a) => {
    if (!today) return true;
    const t = new Date(a.scheduled_start);
    return t >= startOfDay && t <= endOfDay;
  });

  return (
    <div>
      <PageHeader
        title={today ? "برنامه امروز" : "تقویم نوبت‌ها"}
        description="نوبت‌های پزشک از appointments API."
      />
      <div className="space-y-3">
        {items.length === 0 ? (
          <EmptyState title="نوبتی یافت نشد" />
        ) : (
          items.map((a) => (
            <AppointmentCard
              key={a.id}
              appointment={a}
              doctorName={patientName(a.patient_id)}
            />
          ))
        )}
      </div>
    </div>
  );
}

export function DoctorAvailability() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorAvailabilityInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorAvailabilityInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const winQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "availability"],
    queryFn: () => healthcareApi.availabilityWindows.list(tenantId),
    select: (rows) => rows.filter((w) => w.doctor_id === doctorId),
  });
  const schedQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "schedules"],
    queryFn: () => healthcareApi.schedules.list(tenantId),
    select: (rows) => rows.filter((s) => s.doctor_id === doctorId),
  });

  if (winQ.isLoading || schedQ.isLoading) return <HealthcarePageLoader />;
  if (winQ.error) return <HealthcarePageError error={winQ.error} onRetry={() => winQ.refetch()} />;

  return (
    <div>
      <PageHeader title="دسترسی" description="پنجره‌های availability و برنامه هفتگی." />
      <h2 className="mb-3 mt-6 font-semibold text-secondary">پنجره‌های قابل رزرو</h2>
      <DataTable
        columns={[
          { key: "code", header: "کد" },
          {
            key: "starts_at",
            header: "شروع",
            render: (r) => new Date(String(r.starts_at)).toLocaleString("fa-IR"),
          },
          {
            key: "ends_at",
            header: "پایان",
            render: (r) => new Date(String(r.ends_at)).toLocaleString("fa-IR"),
          },
          {
            key: "is_bookable",
            header: "قابل رزرو",
            render: (r) => (
              <Badge tone={r.is_bookable ? "success" : "default"}>
                {r.is_bookable ? "بله" : "خیر"}
              </Badge>
            ),
          },
        ]}
        rows={(winQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={<EmptyState title="پنجره‌ای تعریف نشده" />}
      />
      <h2 className="mb-3 mt-8 font-semibold text-secondary">برنامه هفتگی</h2>
      <DataTable
        columns={[
          { key: "name", header: "نام" },
          { key: "day_of_week", header: "روز" },
          { key: "start_time", header: "شروع" },
          { key: "end_time", header: "پایان" },
        ]}
        rows={(schedQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={<EmptyState title="برنامه‌ای ثبت نشده" />}
      />
    </div>
  );
}

export function DoctorLeaves() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorLeavesInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorLeavesInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const winQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "leaves"],
    queryFn: () => healthcareApi.availabilityWindows.list(tenantId),
    select: (rows) => rows.filter((w) => w.doctor_id === doctorId && !w.is_bookable),
  });

  if (winQ.isLoading) return <HealthcarePageLoader />;
  if (winQ.error) return <HealthcarePageError error={winQ.error} onRetry={() => winQ.refetch()} />;

  return (
    <div>
      <PageHeader title="مرخصی" description="پنجره‌های غیرقابل رزرو (availability-windows)." />
      <DataTable
        columns={[
          { key: "code", header: "کد" },
          {
            key: "starts_at",
            header: "از",
            render: (r) => new Date(String(r.starts_at)).toLocaleString("fa-IR"),
          },
          {
            key: "ends_at",
            header: "تا",
            render: (r) => new Date(String(r.ends_at)).toLocaleString("fa-IR"),
          },
        ]}
        rows={(winQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={<EmptyState title="مرخصی ثبت نشده" />}
      />
    </div>
  );
}

export function DoctorAppointments() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorAppointmentsInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorAppointmentsInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const apptsQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "all-appointments"],
    queryFn: () =>
      healthcareApi.appointments.list(tenantId, { doctor_id: doctorId, page_size: 100 }),
  });
  const { patientName } = useHealthcareLookups();

  if (apptsQ.isLoading) return <HealthcarePageLoader />;
  if (apptsQ.error) return <HealthcarePageError error={apptsQ.error} onRetry={() => apptsQ.refetch()} />;

  return (
    <div>
      <PageHeader title="نوبت‌ها" description={`${apptsQ.data?.total ?? 0} نوبت`} />
      <div className="space-y-3">
        {(apptsQ.data?.items ?? []).map((a) => (
          <AppointmentCard key={a.id} appointment={a} doctorName={patientName(a.patient_id)} />
        ))}
      </div>
    </div>
  );
}

export function DoctorPatients() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorPatientsInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorPatientsInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const apptsQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "patient-ids"],
    queryFn: () =>
      healthcareApi.appointments.list(tenantId, { doctor_id: doctorId, page_size: 100 }),
  });
  const patientsQ = useQuery({
    queryKey: ["healthcare", tenantId, "patients"],
    queryFn: () => healthcareApi.patients.list(tenantId),
  });

  if (apptsQ.isLoading || patientsQ.isLoading) return <HealthcarePageLoader />;
  if (apptsQ.error) return <HealthcarePageError error={apptsQ.error} onRetry={() => apptsQ.refetch()} />;

  const ids = new Set((apptsQ.data?.items ?? []).map((a) => a.patient_id));
  const patients = (patientsQ.data ?? []).filter((p) => ids.has(p.id));

  return (
    <div>
      <PageHeader title="بیماران" description="بیماران با نوبت نزد این پزشک." />
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        {patients.map((p) => (
          <PatientCard key={p.id} patient={p} />
        ))}
      </div>
      {patients.length === 0 ? <EmptyState title="بیماری یافت نشد" /> : null}
    </div>
  );
}

export function DoctorMedicalRecords() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorMedicalRecordsInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorMedicalRecordsInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const visitsQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "visit-sessions"],
    queryFn: () => healthcareApi.visitSessions.list(tenantId, { doctor_id: doctorId }),
  });
  const { patientName } = useHealthcareLookups();

  if (visitsQ.isLoading) return <HealthcarePageLoader />;
  if (visitsQ.error) return <HealthcarePageError error={visitsQ.error} onRetry={() => visitsQ.refetch()} />;

  return (
    <div>
      <PageHeader title="پرونده‌ها" description="جلسات ویزیت پزشک." />
      <div className="space-y-3">
        {(visitsQ.data ?? []).map((v) => (
          <QueueRow
            key={v.id}
            position={v.queue_position}
            title={patientName(v.patient_id)}
            subtitle={v.code}
            status={v.status}
          />
        ))}
      </div>
      {(visitsQ.data ?? []).length === 0 ? <EmptyState title="ویزیتی ثبت نشده" /> : null}
    </div>
  );
}

export function DoctorPrescriptions() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorPrescriptionsInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorPrescriptionsInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const rxQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "rx"],
    queryFn: () => healthcareApi.prescriptionOrders.list(tenantId),
    select: (rows) => rows.filter((r) => r.doctor_id === doctorId),
  });

  if (rxQ.isLoading) return <HealthcarePageLoader />;
  if (rxQ.error) return <HealthcarePageError error={rxQ.error} onRetry={() => rxQ.refetch()} />;

  return (
    <div>
      <PageHeader title="نسخه‌ها" description="نسخه‌های صادرشده توسط پزشک." />
      <div className="space-y-3">
        {(rxQ.data ?? []).map((o) => (
          <PrescriptionCard key={o.id} order={o} />
        ))}
      </div>
      {(rxQ.data ?? []).length === 0 ? <EmptyState title="نسخه‌ای ثبت نشده" /> : null}
    </div>
  );
}

export function DoctorReports() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorReportsInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorReportsInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const dashQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "reports-dash"],
    queryFn: () => healthcareApi.doctorPanel.dashboard(tenantId, doctorId),
  });
  const apptsQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "reports-appts"],
    queryFn: () =>
      healthcareApi.appointments.list(tenantId, { doctor_id: doctorId, page_size: 1 }),
  });

  if (dashQ.isLoading) return <HealthcarePageLoader />;
  if (dashQ.error) return <HealthcarePageError error={dashQ.error} onRetry={() => dashQ.refetch()} />;

  return (
    <div>
      <PageHeader title="گزارش‌ها" description="خلاصه عملکرد پزشک." />
      <AggregateStatsRow
        stats={[
          { label: "کل نوبت‌ها", value: apptsQ.data?.total ?? 0 },
          { label: "تکمیل امروز", value: dashQ.data?.completed_today_count ?? 0 },
          { label: "در صف", value: dashQ.data?.queued_count ?? 0 },
        ]}
      />
    </div>
  );
}

export function DoctorAnalytics() {
  return <AnalyticsPage title="آنالیتیکس پزشک" />;
}

export function DoctorIncome() {
  return (
    <DoctorGate>
      {(ctx) => <DoctorIncomeInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />}
    </DoctorGate>
  );
}

function DoctorIncomeInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const apptsQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "income-appts"],
    queryFn: () =>
      healthcareApi.appointments.list(tenantId, { doctor_id: doctorId, status: "completed", page_size: 1 }),
  });
  const rxQ = useQuery({
    queryKey: ["healthcare", tenantId, doctorId, "income-rx"],
    queryFn: () => healthcareApi.prescriptionOrders.list(tenantId),
    select: (rows) => rows.filter((r) => r.doctor_id === doctorId),
  });

  if (apptsQ.isLoading) return <HealthcarePageLoader />;

  return (
    <div>
      <PageHeader title="درآمد" description="برآورد از نوبت‌های تکمیل‌شده و نسخه‌ها." />
      <div className="grid gap-4 sm:grid-cols-2">
        <StatWidget label="ویزیت تکمیل‌شده" value={apptsQ.data?.total ?? 0} />
        <StatWidget label="نسخه صادرشده" value={rxQ.data?.length ?? 0} />
      </div>
    </div>
  );
}

export function DoctorNotifications() {
  return <SettingsListPage title="اعلان‌ها" description="تنظیمات اعلان workspace." />;
}

export function DoctorMessages() {
  return (
    <DoctorGate>
      {(ctx) => (
        <DoctorMessagesInner tenantId={ctx.tenantId!} doctorId={ctx.doctorId!} />
      )}
    </DoctorGate>
  );
}

function DoctorMessagesInner({ tenantId, doctorId }: { tenantId: string; doctorId: string }) {
  const logsQ = useQuery({
    queryKey: ["healthcare", tenantId, "audit", "doctor", doctorId],
    queryFn: () => healthcareApi.audit.list(tenantId, "doctor", doctorId),
  });

  if (logsQ.isLoading) return <HealthcarePageLoader />;
  if (logsQ.error) return <HealthcarePageError error={logsQ.error} onRetry={() => logsQ.refetch()} />;

  return (
    <div>
      <PageHeader title="پیام‌ها" description="رویدادهای audit پزشک." />
      <DataTable
        columns={[
          { key: "action", header: "عملیات" },
          { key: "message", header: "پیام", render: (r) => String(r.message ?? "—") },
          {
            key: "created_at",
            header: "زمان",
            render: (r) => new Date(String(r.created_at)).toLocaleString("fa-IR"),
          },
        ]}
        rows={(logsQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={<EmptyState title="پیامی ثبت نشده" />}
      />
    </div>
  );
}

export function DoctorSettings() {
  return <SettingsListPage title="تنظیمات پزشک" description="تنظیمات workspace." />;
}
