"use client";

import { ActionForm } from "@/components/action-form";
import { startTransition, useActionState, useState } from "react";
import { useFormStatus } from "react-dom";
import {
  checkInAction,
  saveDailyReportAction,
  setPlanItemStatusAction,
  type CheckInState,
  type ReportState,
} from "../actions";
import { Badge } from "@/components/ui";
import { compressImage, type CompressResult } from "@/lib/image-compress";
import { formatBytes } from "@/lib/format";

export type TodayItem = {
  id: string;
  content: string;
  objective: string | null;
  timeSlot: string | null;
  status: "PLANNED" | "DONE" | "MISSED";
  customerId: string | null;
  customerName: string | null;
  customerAddress: string | null;
  checkedIn: boolean;
};

export type ExistingReport = {
  content: string | null;
  results: string | null;
  proposals: string | null;
  pending: string | null;
  nextSteps: string | null;
  routeCompliant: boolean;
} | null;

/**
 * Nút check-in.
 *
 * Toạ độ lấy từ trình duyệt ngay lúc bấm; việc tính khoảng cách tới điểm bán do
 * máy chủ làm. Không dùng vị trí đã lưu sẵn trong bộ nhớ để tránh check-in hộ.
 */
function CheckInButton({
  customerId,
  planItemId,
  onDone,
}: {
  customerId: string;
  planItemId: string;
  onDone: (message: string) => void;
}) {
  const [state, runCheckIn] = useActionState<CheckInState, FormData>(checkInAction, {});
  const [locating, setLocating] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [photo, setPhoto] = useState<CompressResult | null>(null);
  const [shrinking, setShrinking] = useState(false);

  const handlePhoto = async (file: File | null) => {
    if (!file) {
      setPhoto(null);
      return;
    }
    // Nén trước khi giữ vào state, để lúc bấm Check-in là gửi đi được ngay —
    // NVKD đã đứng sẵn trước cửa hàng, không nên bắt họ chờ thêm lần nữa.
    setShrinking(true);
    setPhoto(await compressImage(file));
    setShrinking(false);
  };

  const handleClick = () => {
    if (!navigator.geolocation) {
      setError("Thiết bị không hỗ trợ định vị.");
      return;
    }

    setLocating(true);
    setError(null);

    navigator.geolocation.getCurrentPosition(
      (position) => {
        const formData = new FormData();
        formData.set("customerId", customerId);
        formData.set("planItemId", planItemId);
        formData.set("lat", String(position.coords.latitude));
        formData.set("lng", String(position.coords.longitude));
        formData.set("accuracy", String(position.coords.accuracy ?? ""));
        if (photo) formData.set("photo", photo.file);
        // Hàm dispatch của useActionState phải gọi trong transition, không phải
        // gọi tay trong callback bất đồng bộ của getCurrentPosition — thiếu bước
        // này React vẫn chạy được nhưng cảnh báo, và state.error dựng chậm hơn.
        startTransition(() => {
          runCheckIn(formData);
        });
        setLocating(false);
        onDone("");
      },
      (positionError) => {
        setLocating(false);
        setError(
          positionError.code === positionError.PERMISSION_DENIED
            ? "Bạn cần cho phép truy cập vị trí để check-in."
            : "Chưa lấy được vị trí. Ra ngoài trời hoặc thử lại sau vài giây.",
        );
      },
      { enableHighAccuracy: true, timeout: 15_000, maximumAge: 0 },
    );
  };

  return (
    <div className="flex flex-col items-end gap-1.5">
      {/* capture="environment" mở thẳng camera sau trên điện thoại thay vì thư viện ảnh */}
      <label className="cursor-pointer text-right text-[11px] text-brand-600 underline">
        {shrinking ? "Đang xử lý ảnh…" : photo ? "Đổi ảnh khác" : "+ Chụp ảnh (tuỳ chọn)"}
        <input
          type="file"
          accept="image/*"
          capture="environment"
          className="sr-only"
          onChange={(event) => {
            void handlePhoto(event.target.files?.[0] ?? null);
          }}
        />
      </label>

      {/* Cho NVKD thấy ảnh đã nhẹ đi bao nhiêu — họ đang dùng 3G/4G và tự trả tiền
          dung lượng, nên con số này là thông tin có ích chứ không phải khoe kỹ thuật. */}
      {photo && !shrinking && (
        <span className="tnum text-right text-[11px] text-ink-400">
          {photo.compressed
            ? `Ảnh đã sẵn sàng · ${formatBytes(photo.originalBytes)} → ${formatBytes(photo.bytes)}`
            : `Ảnh đã sẵn sàng · ${formatBytes(photo.bytes)}`}
        </span>
      )}

      <button
        type="button"
        onClick={handleClick}
        disabled={locating || shrinking}
        className="btn-primary px-3 py-1.5 text-xs"
      >
        {locating ? "Đang định vị…" : "Check-in"}
      </button>

      {(error || state.error) && (
        <span className="text-right text-[11px] text-red-600">{error ?? state.error}</span>
      )}
      {state.message && <span className="text-right text-[11px] text-brand-600">{state.message}</span>}
    </div>
  );
}

/**
 * Báo một điểm không đi được, kèm lý do.
 *
 * Hỏi lý do ngay lúc bỏ điểm chứ không để tới cuối tuần — tới lúc chốt tuần thì
 * NVKD đã quên vì sao, và bản tổng kết chỉ còn những dòng "bận việc khác".
 */
function MissedForm({ planItemId }: { planItemId: string }) {
  const [open, setOpen] = useState(false);

  if (!open) {
    return (
      <button type="button" onClick={() => setOpen(true)} className="btn-ghost px-3 py-1.5 text-xs">
        Không đi được
      </button>
    );
  }

  return (
    <ActionForm action={setPlanItemStatusAction} success="Đã cập nhật công việc." className="flex flex-col items-end gap-1.5">
      <input type="hidden" name="id" value={planItemId} />
      <input type="hidden" name="status" value="MISSED" />
      <input
        name="missedReason"
        required
        maxLength={300}
        autoFocus
        className="input w-48 py-1 text-sm"
        placeholder="Lý do không đi được"
      />
      <div className="flex gap-1.5">
        <button type="button" onClick={() => setOpen(false)} className="btn-ghost px-2 py-1 text-xs">
          Bỏ
        </button>
        <button type="submit" className="btn-primary px-3 py-1 text-xs">
          Lưu
        </button>
      </div>
    </ActionForm>
  );
}

function SaveButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className="btn-primary" disabled={pending}>
      {pending ? "Đang lưu…" : "Gửi báo cáo ngày"}
    </button>
  );
}

export function TodayClient({
  items,
  reportDate,
  existingReport,
}: {
  items: TodayItem[];
  reportDate: string;
  existingReport: ExistingReport;
}) {
  const [reportState, saveReport] = useActionState<ReportState, FormData>(saveDailyReportAction, {});
  const [, setToast] = useState("");

  const done = items.filter((item) => item.status === "DONE").length;
  const completionPct = items.length > 0 ? Math.round((done / items.length) * 100) : 0;

  return (
    <div className="flex flex-col gap-5">
      {/* Lộ trình hôm nay */}
      <section>
        <div className="mb-3 flex items-baseline justify-between">
          <h2 className="text-base font-bold text-ink-700">Lộ trình hôm nay</h2>
          <span className="tnum text-sm text-ink-400">
            {done}/{items.length} điểm · {completionPct}%
          </span>
        </div>

        {items.length === 0 ? (
          <div className="card px-4 py-8 text-center text-sm text-ink-400">
            Hôm nay chưa có điểm nào trong kế hoạch tuần.
          </div>
        ) : (
          <ul className="flex flex-col gap-2">
            {items.map((item) => (
              <li key={item.id} className="card flex flex-wrap items-start gap-3 p-4">
                <span className="tnum w-20 shrink-0 pt-0.5 text-xs text-ink-400">
                  {item.timeSlot ?? "—"}
                </span>

                <div className="min-w-40 flex-1">
                  <div className="text-sm font-medium text-ink-700">{item.content}</div>
                  {item.customerName && (
                    <div className="text-xs text-ink-500">{item.customerName}</div>
                  )}
                  {item.customerAddress && (
                    <div className="text-[11px] text-ink-400">{item.customerAddress}</div>
                  )}
                  {item.objective && (
                    <div className="mt-1 text-[11px] text-ink-400">Mục tiêu: {item.objective}</div>
                  )}
                  <div className="mt-1.5 flex flex-wrap items-center gap-2">
                    <Badge
                      tone={item.status === "DONE" ? "green" : item.status === "MISSED" ? "red" : "neutral"}
                    >
                      {{ DONE: "Đã làm", MISSED: "Chưa đạt", PLANNED: "Chưa đi" }[item.status]}
                    </Badge>
                    {item.checkedIn && <Badge tone="brand">Đã check-in</Badge>}
                  </div>
                </div>

                <div className="flex flex-col items-end gap-2">
                  {item.customerId && !item.checkedIn && (
                    <CheckInButton
                      customerId={item.customerId}
                      planItemId={item.id}
                      onDone={(message) => setToast(message)}
                    />
                  )}
                  {item.status === "PLANNED" && <MissedForm planItemId={item.id} />}
                </div>
              </li>
            ))}
          </ul>
        )}
      </section>

      {/* Báo cáo ngày */}
      <section>
        <h2 className="mb-3 text-base font-bold text-ink-700">Báo cáo kết quả trong ngày</h2>
        <form action={saveReport} className="card flex flex-col gap-4 p-4">
          <input type="hidden" name="reportDate" value={reportDate} />

          <div className="rounded-lg bg-ink-50 px-3 py-2 text-xs text-ink-500">
            % thực hiện được tính tự động từ lộ trình đã đăng ký — hiện tại{" "}
            <span className="font-semibold text-ink-700">{completionPct}%</span>. Đánh dấu từng điểm ở
            trên để con số này thay đổi.
          </div>

          <div>
            <label htmlFor="results" className="label-caps mb-1.5 block">
              Kết quả đạt được
            </label>
            <textarea
              id="results"
              name="results"
              rows={3}
              defaultValue={existingReport?.results ?? ""}
              className="input"
              placeholder="Chốt mấy đơn, giới thiệu sản phẩm gì, phản hồi của khách…"
            />
          </div>

          <div>
            <label htmlFor="pending" className="label-caps mb-1.5 block">
              Tồn đọng — việc chưa thực hiện được
            </label>
            <textarea
              id="pending"
              name="pending"
              rows={2}
              defaultValue={existingReport?.pending ?? ""}
              className="input"
              placeholder="Điểm nào chưa gặp được, lý do…"
            />
          </div>

          <div>
            <label htmlFor="proposals" className="label-caps mb-1.5 block">
              Kiến nghị / đề xuất
            </label>
            <textarea
              id="proposals"
              name="proposals"
              rows={2}
              defaultValue={existingReport?.proposals ?? ""}
              className="input"
              placeholder="Đề xuất chính sách, hàng mẫu, hỗ trợ…"
            />
          </div>

          <div>
            <label htmlFor="nextSteps" className="label-caps mb-1.5 block">
              Hướng triển khai sắp tới
            </label>
            <textarea
              id="nextSteps"
              name="nextSteps"
              rows={2}
              defaultValue={existingReport?.nextSteps ?? ""}
              className="input"
            />
          </div>

          <label className="flex items-center gap-2 text-sm text-ink-600">
            <input
              type="checkbox"
              name="routeCompliant"
              defaultChecked={existingReport?.routeCompliant ?? true}
              className="h-4 w-4 accent-brand-500"
            />
            Đã đi đúng kế hoạch và lộ trình đăng ký
          </label>

          {reportState.error && (
            <p role="alert" className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
              {reportState.error}
            </p>
          )}
          {reportState.ok && (
            <p className="rounded-lg bg-ink-100 px-3 py-2 text-sm text-brand-600">
              Đã gửi báo cáo ngày {reportDate.split("-").reverse().join("/")}.
            </p>
          )}

          <div>
            <SaveButton />
          </div>
        </form>
      </section>
    </div>
  );
}
