import * as icon from '@mdi/js';
import axios from 'axios';
import dayjs from 'dayjs';
import Head from 'next/head';
import React, {
  ChangeEvent,
  ReactElement,
  useCallback,
  useEffect,
  useMemo,
  useState,
} from 'react';

import BaseButton from '../components/BaseButton';
import BaseButtons from '../components/BaseButtons';
import BaseIcon from '../components/BaseIcon';
import CardBox from '../components/CardBox';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import FileUploader from '../components/Uploaders/UploadService';
import { getPageTitle } from '../config';
import { hasPermission } from '../helpers/userPermissions';
import LayoutAuthenticated from '../layouts/Authenticated';
import { useAppSelector } from '../stores/hooks';

type ClockInEmployee = {
  id: string;
  employee_code: string | null;
  full_name: string | null;
  phone: string | null;
  userId: string | null;
  outletId: string | null;
  job_positionId: string | null;
};

type ClockInOutlet = {
  id: string;
  code: string | null;
  name: string | null;
  address: string | null;
  gps_lat: number | null;
  gps_lng: number | null;
  gps_radius_m: number | null;
  is_active: boolean;
};

type ClockInJobPosition = {
  id: string;
  code: string | null;
  name: string | null;
  payroll_weight: number | null;
  is_active: boolean;
  shift_schedule: string | null;
  shift_times: string[];
};

type ClockInFile = {
  id: string;
  name: string;
  sizeInBytes: number;
  privateUrl: string;
  publicUrl: string;
  new?: boolean;
};

type ClockInLog = {
  id: string;
  work_date: string | null;
  check_in_at: string | null;
  check_out_at: string | null;
  check_in_lat: number | null;
  check_in_lng: number | null;
  check_out_lat: number | null;
  check_out_lng: number | null;
  status: string | null;
  late_minutes: number | null;
  gps_valid: boolean;
  remarks: string | null;
  employee: ClockInEmployee | null;
  outlet: ClockInOutlet | null;
  check_in_photo: ClockInFile[];
  check_out_photo: ClockInFile[];
};

type RosterShift = {
  label: string;
  time: string;
  startsAt: string;
  windowStartAt: string;
  windowEndAt: string;
  windowLabel: string;
  lateMinutes: number;
  latePenaltyAmount: number;
  status: string;
  withinWindow: boolean;
};

type ClockInRoster = {
  latePenaltyPerMinute: number;
  windowBeforeMinutes: number;
  windowAfterMinutes: number;
  shiftScheduleRaw: string | null;
  shiftTimes: string[];
  activeShift: RosterShift | null;
  nextShift: RosterShift | null;
  assignedShift: RosterShift | null;
  blockedReason: string | null;
};

type ClockInContext = {
  employee: ClockInEmployee | null;
  outlet: ClockInOutlet | null;
  jobPosition: ClockInJobPosition | null;
  todayLog: ClockInLog | null;
  canClockIn: boolean;
  setupError: string | null;
  clockInBlockedReason: string | null;
  roster: ClockInRoster;
  timezoneOffsetMinutes: number;
};

type ClockInResponse = {
  success: boolean;
  action: 'created' | 'updated';
  attendanceLog: ClockInLog;
  jobPosition: ClockInJobPosition | null;
  roster: ClockInRoster;
  timezoneOffsetMinutes: number;
};

type LocationState = {
  latitude: number;
  longitude: number;
  accuracy: number | null;
  capturedAt: string;
};

const pageIcon =
  'mdiCellphoneMarker' in icon
    ? icon['mdiCellphoneMarker' as keyof typeof icon]
    : icon.mdiMapMarkerCheck ?? icon.mdiTable;
const gpsIcon =
  'mdiCrosshairsGps' in icon
    ? icon['mdiCrosshairsGps' as keyof typeof icon]
    : icon.mdiMapMarkerCheck ?? icon.mdiTable;
const selfieIcon =
  'mdiCameraOutline' in icon
    ? icon['mdiCameraOutline' as keyof typeof icon]
    : icon.mdiUpload ?? icon.mdiTable;
const successIcon =
  'mdiCheckCircleOutline' in icon
    ? icon['mdiCheckCircleOutline' as keyof typeof icon]
    : icon.mdiCheckCircle ?? icon.mdiTable;
const warningIcon =
  'mdiAlertCircleOutline' in icon
    ? icon['mdiAlertCircleOutline' as keyof typeof icon]
    : icon.mdiAlert ?? icon.mdiTable;
const refreshIcon = icon.mdiReload ?? icon.mdiTable;
const detailIcon =
  'mdiOpenInNew' in icon
    ? icon['mdiOpenInNew' as keyof typeof icon]
    : icon.mdiArrowRightBoldCircleOutline ?? icon.mdiTable;
const calendarIcon =
  'mdiCalendarClock' in icon
    ? icon['mdiCalendarClock' as keyof typeof icon]
    : icon.mdiCalendar ?? icon.mdiTable;
const shiftIcon =
  'mdiClockOutline' in icon
    ? icon['mdiClockOutline' as keyof typeof icon]
    : icon.mdiClock ?? icon.mdiTable;
const officeIcon =
  'mdiStoreMarker' in icon
    ? icon['mdiStoreMarker' as keyof typeof icon]
    : icon.mdiStore ?? icon.mdiTable;
const teamIcon =
  'mdiAccountTieOutline' in icon
    ? icon['mdiAccountTieOutline' as keyof typeof icon]
    : icon.mdiAccount ?? icon.mdiTable;

const inputClassName =
  'w-full rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 shadow-sm outline-none transition focus:border-teal-500 focus:ring focus:ring-teal-200';

const formatDateTime = (value?: string | null) => {
  if (!value) {
    return '—';
  }

  return dayjs(value).format('DD MMM YYYY • HH:mm');
};

const formatTime = (value?: string | null) => {
  if (!value) {
    return '—';
  }

  return dayjs(value).format('HH:mm');
};

const formatCurrency = (value?: number | null) =>
  new Intl.NumberFormat('id-ID', {
    style: 'currency',
    currency: 'IDR',
    maximumFractionDigits: 0,
  }).format(Number.isFinite(value) ? Number(value) : 0);

const getErrorMessage = (error: unknown) => {
  if (axios.isAxiosError(error)) {
    if (typeof error.response?.data === 'string' && error.response.data) {
      return error.response.data;
    }

    if (
      error.response?.data &&
      typeof error.response.data === 'object' &&
      error.response.data !== null &&
      'message' in error.response.data &&
      typeof error.response.data.message === 'string'
    ) {
      return error.response.data.message;
    }

    return error.message;
  }

  if (error instanceof Error) {
    return error.message;
  }

  return 'Terjadi kesalahan saat memproses clock in.';
};

const getStatusBadgeClasses = (status?: string | null) => {
  if (status === 'telat') {
    return 'border border-amber-200 bg-amber-50 text-amber-700';
  }

  if (status === 'hadir') {
    return 'border border-emerald-200 bg-emerald-50 text-emerald-700';
  }

  return 'border border-slate-200 bg-slate-50 text-slate-700';
};

const getChecklistBadgeClasses = (ok: boolean) =>
  ok ? 'bg-emerald-100 text-emerald-700' : 'bg-slate-200 text-slate-600';

const ClockInPage = () => {
  const { currentUser } = useAppSelector((state) => state.auth);
  const canReadAttendanceLogs = hasPermission(currentUser, 'READ_ATTENDANCE_LOGS');
  const timezoneOffsetMinutes = useMemo(() => new Date().getTimezoneOffset(), []);

  const [context, setContext] = useState<ClockInContext | null>(null);
  const [result, setResult] = useState<ClockInResponse | null>(null);
  const [remarks, setRemarks] = useState('');
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [previewUrl, setPreviewUrl] = useState('');
  const [location, setLocation] = useState<LocationState | null>(null);
  const [manualLatitude, setManualLatitude] = useState('');
  const [manualLongitude, setManualLongitude] = useState('');
  const [pageError, setPageError] = useState('');
  const [submitError, setSubmitError] = useState('');
  const [locationError, setLocationError] = useState('');
  const [isLoadingContext, setIsLoadingContext] = useState(true);
  const [isLocating, setIsLocating] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);

  const todayLog = context?.todayLog || result?.attendanceLog || null;
  const roster = context?.roster || result?.roster || null;
  const jobPosition = context?.jobPosition || result?.jobPosition || null;
  const hasClockedIn = Boolean(todayLog?.check_in_at);
  const lateMinutes = typeof todayLog?.late_minutes === 'number' ? todayLog.late_minutes : 0;
  const latePenaltyAmount = lateMinutes * (roster?.latePenaltyPerMinute || 0);
  const employeeLabel =
    context?.employee?.full_name ||
    currentUser?.employees_user?.[0]?.full_name ||
    currentUser?.firstName ||
    currentUser?.email ||
    'Belum terhubung';
  const outletLabel = context?.outlet?.name || 'Belum ada outlet';
  const availableShiftLabel = roster?.shiftTimes.length ? roster.shiftTimes.join(', ') : 'Belum diatur';

  useEffect(() => {
    if (!selectedFile) {
      setPreviewUrl('');
      return undefined;
    }

    const nextPreviewUrl = URL.createObjectURL(selectedFile);
    setPreviewUrl(nextPreviewUrl);

    return () => {
      URL.revokeObjectURL(nextPreviewUrl);
    };
  }, [selectedFile]);

  const loadClockInContext = useCallback(async () => {
    setIsLoadingContext(true);
    setPageError('');

    try {
      const response = await axios.get<ClockInContext>('/attendance_logs/clock-in', {
        params: {
          timezoneOffsetMinutes,
        },
      });

      setContext(response.data);
    } catch (error) {
      console.error('Failed to load clock-in context:', error);
      setPageError(getErrorMessage(error));
    } finally {
      setIsLoadingContext(false);
    }
  }, [timezoneOffsetMinutes]);

  const requestLocation = useCallback(async () => {
    if (typeof window === 'undefined' || !navigator.geolocation) {
      setLocation(null);
      setLocationError('Browser ini belum mendukung GPS otomatis. Isi koordinat manual untuk testing.');
      return;
    }

    setIsLocating(true);
    setLocationError('');

    await new Promise<void>((resolve) => {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          setLocation({
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
            accuracy: position.coords.accuracy,
            capturedAt: new Date().toISOString(),
          });
          setManualLatitude('');
          setManualLongitude('');
          setIsLocating(false);
          resolve();
        },
        (error) => {
          console.error('Failed to get geolocation:', error);
          setLocation(null);
          setLocationError(
            'GPS tidak bisa diambil otomatis. Izinkan location di browser, atau isi koordinat manual untuk testing dev.',
          );
          setIsLocating(false);
          resolve();
        },
        {
          enableHighAccuracy: true,
          timeout: 15000,
          maximumAge: 0,
        },
      );
    });
  }, []);

  useEffect(() => {
    void loadClockInContext();
    void requestLocation();
  }, [loadClockInContext, requestLocation]);

  const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
    const nextFile = event.target.files?.[0] ?? null;
    setSelectedFile(nextFile);
  };

  const handleClockIn = async () => {
    setSubmitError('');

    if (!context) {
      setSubmitError('Context clock in belum siap. Coba refresh halaman.');
      return;
    }

    if (!context.canClockIn) {
      setSubmitError(
        context.clockInBlockedReason || context.setupError || 'Clock in belum bisa dilakukan sekarang.',
      );
      return;
    }

    if (!selectedFile) {
      setSubmitError('Ambil atau unggah foto selfie terlebih dulu.');
      return;
    }

    const latitude = location?.latitude ?? Number(manualLatitude);
    const longitude = location?.longitude ?? Number(manualLongitude);

    if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
      setSubmitError('GPS belum tersedia. Klik “Ambil GPS lagi”, atau isi koordinat manual untuk testing dev.');
      return;
    }

    setIsSubmitting(true);

    try {
      const uploadedPhoto = (await FileUploader.upload(
        'attendance_logs/check_in_photo',
        selectedFile,
        { image: true },
      )) as ClockInFile;

      const response = await axios.post<ClockInResponse>('/attendance_logs/clock-in', {
        latitude,
        longitude,
        remarks,
        check_in_photo: [uploadedPhoto],
        clientTimestamp: new Date().toISOString(),
        timezoneOffsetMinutes,
      });

      setResult(response.data);
      setSelectedFile(null);
      setRemarks('');
      await loadClockInContext();
    } catch (error) {
      console.error('Clock-in request failed:', error);
      setSubmitError(getErrorMessage(error));
    } finally {
      setIsSubmitting(false);
    }
  };

  const checklistItems = [
    {
      label: 'User terhubung ke employee',
      ok: Boolean(context?.employee),
    },
    {
      label: 'Employee terhubung ke outlet',
      ok: Boolean(context?.outlet),
    },
    {
      label: 'Employee terhubung ke divisi/job position',
      ok: Boolean(jobPosition),
    },
    {
      label: 'Jadwal shift sudah dikonfigurasi',
      ok: Boolean(roster?.shiftTimes.length),
    },
    {
      label: 'Sedang berada di window shift yang valid',
      ok: Boolean(roster?.activeShift?.withinWindow),
    },
    {
      label: 'GPS tersedia',
      ok:
        typeof location?.latitude === 'number' ||
        (manualLatitude.trim() !== '' && manualLongitude.trim() !== ''),
    },
    {
      label: 'Foto selfie dipilih',
      ok: Boolean(selectedFile),
    },
    {
      label: 'Belum ada clock in hari ini',
      ok: !hasClockedIn,
    },
  ];

  return (
    <>
      <Head>
        <title>{getPageTitle('Clock in')}</title>
      </Head>

      <SectionMain>
        <SectionTitleLineWithButton icon={pageIcon} title="Clock in" main>
          {''}
        </SectionTitleLineWithButton>

        <div className="space-y-6">
          <CardBox className="overflow-hidden bg-gradient-to-br from-slate-950 via-slate-900 to-teal-900 text-white shadow-xl">
            <div className="grid gap-6 lg:grid-cols-[1.2fr,0.8fr]">
              <div className="space-y-4">
                <div className="inline-flex items-center gap-2 rounded-full border border-white/20 bg-white/10 px-3 py-1 text-sm font-medium text-slate-100 backdrop-blur">
                  <BaseIcon path={pageIcon} size={18} />
                  Flow Clock In Otomatis v2
                </div>
                <div>
                  <h2 className="text-2xl font-semibold md:text-3xl">
                    Clock in otomatis dengan roster shift, GPS, selfie, dan denda telat per menit.
                  </h2>
                  <p className="mt-3 max-w-2xl text-sm text-slate-200 md:text-base">
                    Sistem akan otomatis mencocokkan absensi ke shift yang tersedia pada divisi user.
                    Clock in hanya boleh dilakukan 60 menit sebelum sampai 60 menit sesudah shift
                    dimulai.
                  </p>
                </div>
              </div>

              <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-1">
                <div className="rounded-2xl border border-white/15 bg-white/10 p-4 backdrop-blur">
                  <div className="text-xs uppercase tracking-[0.2em] text-slate-300">Employee</div>
                  <div className="mt-2 text-lg font-semibold">{employeeLabel}</div>
                  <div className="mt-1 text-sm text-slate-300">
                    {context?.employee?.employee_code || 'Employee code belum ada'}
                  </div>
                </div>
                <div className="rounded-2xl border border-white/15 bg-white/10 p-4 backdrop-blur">
                  <div className="text-xs uppercase tracking-[0.2em] text-slate-300">Outlet</div>
                  <div className="mt-2 text-lg font-semibold">{outletLabel}</div>
                  <div className="mt-1 text-sm text-slate-300">
                    {context?.outlet?.address || 'Hubungkan employee ke outlet untuk auto clock in'}
                  </div>
                </div>
                <div className="rounded-2xl border border-white/15 bg-white/10 p-4 backdrop-blur sm:col-span-2 lg:col-span-1">
                  <div className="text-xs uppercase tracking-[0.2em] text-slate-300">Divisi & shift</div>
                  <div className="mt-2 text-lg font-semibold">{jobPosition?.name || 'Belum ada job position'}</div>
                  <div className="mt-1 text-sm text-slate-300">{availableShiftLabel}</div>
                </div>
              </div>
            </div>
          </CardBox>

          {pageError ? (
            <div className="rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
              {pageError}
            </div>
          ) : null}

          {context?.setupError ? (
            <div className="rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
              {context.setupError} Minta admin memastikan employee, outlet, dan job position sudah terhubung.
            </div>
          ) : null}

          {!context?.setupError && context?.clockInBlockedReason && !hasClockedIn ? (
            <div className="rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
              {context.clockInBlockedReason}
            </div>
          ) : null}

          {result?.success ? (
            <div className="rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-4 text-emerald-800">
              <div className="flex items-start gap-3">
                <div className="mt-0.5 inline-flex h-9 w-9 items-center justify-center rounded-full bg-emerald-100 text-emerald-700">
                  <BaseIcon path={successIcon} size={20} />
                </div>
                <div className="flex-1">
                  <div className="font-semibold">Clock in berhasil disimpan.</div>
                  <div className="mt-1 text-sm leading-6">
                    {result.action === 'updated' ? 'Record hari ini diperbarui.' : 'Record baru dibuat.'}{' '}
                    Jam masuk: {formatDateTime(result.attendanceLog.check_in_at)}.
                    {result.roster.assignedShift
                      ? ` Shift terpilih otomatis: ${result.roster.assignedShift.label} (${result.roster.assignedShift.windowLabel}).`
                      : ''}
                    {typeof result.attendanceLog.late_minutes === 'number'
                      ? ` Keterlambatan: ${result.attendanceLog.late_minutes} menit.`
                      : ''}
                  </div>
                  {canReadAttendanceLogs ? (
                    <BaseButtons type="justify-start" mb="mt-3 -mb-1" classAddon="mr-2 mb-1 last:mr-0">
                      <BaseButton
                        color="success"
                        icon={detailIcon}
                        label="Lihat detail log"
                        href={`/attendance_logs/${result.attendanceLog.id}`}
                      />
                      <BaseButton
                        color="white"
                        icon={detailIcon}
                        label="Buka attendance logs"
                        href="/attendance_logs/attendance_logs-list"
                      />
                    </BaseButtons>
                  ) : null}
                </div>
              </div>
            </div>
          ) : null}

          <div className="grid gap-6 xl:grid-cols-[1.25fr,0.75fr]">
            <div className="space-y-6">
              <CardBox>
                <div className="space-y-6">
                  <div className="flex flex-col gap-4 md:flex-row md:items-start md:justify-between">
                    <div>
                      <div className="text-sm font-medium text-slate-500">Status hari ini</div>
                      <h3 className="mt-1 text-xl font-semibold text-slate-900">
                        {dayjs().format('dddd, DD MMMM YYYY')}
                      </h3>
                      <p className="mt-2 text-sm text-slate-500">
                        Refresh halaman ini jika admin baru saja mengubah job position atau jadwal shift user.
                      </p>
                    </div>
                    <span
                      className={`inline-flex items-center gap-2 rounded-full px-3 py-1 text-sm font-medium ${getStatusBadgeClasses(
                        hasClockedIn ? todayLog?.status : roster?.activeShift?.status,
                      )}`}
                    >
                      <BaseIcon path={hasClockedIn ? successIcon : warningIcon} size={18} />
                      {hasClockedIn
                        ? todayLog?.status === 'telat'
                          ? 'Sudah clock in • telat'
                          : 'Sudah clock in'
                        : roster?.activeShift
                          ? `Shift aktif • ${roster.activeShift.label}`
                          : 'Belum clock in'}
                    </span>
                  </div>

                  <div className="grid gap-4 md:grid-cols-3">
                    <div className="rounded-2xl border border-slate-200 bg-slate-50/80 p-4">
                      <div className="flex items-center gap-2 text-sm font-medium text-slate-500">
                        <BaseIcon path={calendarIcon} size={18} />
                        Jam masuk tercatat
                      </div>
                      <div className="mt-2 text-2xl font-semibold text-slate-900">
                        {todayLog?.check_in_at ? formatTime(todayLog.check_in_at) : '—'}
                      </div>
                      <div className="mt-2 text-sm text-slate-500">
                        {todayLog?.check_in_at
                          ? formatDateTime(todayLog.check_in_at)
                          : 'Belum ada record check in untuk hari ini.'}
                      </div>
                    </div>

                    <div className="rounded-2xl border border-slate-200 bg-slate-50/80 p-4">
                      <div className="flex items-center gap-2 text-sm font-medium text-slate-500">
                        <BaseIcon path={shiftIcon} size={18} />
                        Shift yang dipakai
                      </div>
                      <div className="mt-2 text-2xl font-semibold text-slate-900">
                        {roster?.assignedShift?.label || roster?.activeShift?.label || '—'}
                      </div>
                      <div className="mt-2 text-sm text-slate-500">
                        {roster?.assignedShift
                          ? `Window shift: ${roster.assignedShift.windowLabel}`
                          : roster?.nextShift
                            ? `Window berikutnya: ${roster.nextShift.windowLabel}`
                            : 'Belum ada shift yang cocok untuk waktu sekarang.'}
                      </div>
                    </div>

                    <div className="rounded-2xl border border-slate-200 bg-slate-50/80 p-4">
                      <div className="flex items-center gap-2 text-sm font-medium text-slate-500">
                        <BaseIcon path={warningIcon} size={18} />
                        Keterlambatan & denda
                      </div>
                      <div className="mt-2 text-2xl font-semibold text-slate-900">{lateMinutes} menit</div>
                      <div className="mt-2 text-sm text-slate-500">
                        Denda estimasi: {formatCurrency(latePenaltyAmount)}
                      </div>
                    </div>
                  </div>

                  <div className="grid gap-4 md:grid-cols-2">
                    <div className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
                      <div className="flex items-center gap-2 text-slate-900">
                        <BaseIcon path={teamIcon} size={20} className="text-teal-600" />
                        <h4 className="text-lg font-semibold">Konfigurasi roster divisi</h4>
                      </div>
                      <div className="mt-4 space-y-3 text-sm text-slate-600">
                        <div className="flex items-start justify-between gap-4">
                          <span className="text-slate-500">Job position</span>
                          <span className="text-right font-semibold text-slate-950">
                            {jobPosition?.name || 'Belum diatur'}
                          </span>
                        </div>
                        <div className="flex items-start justify-between gap-4">
                          <span className="text-slate-500">Jam shift</span>
                          <span className="text-right font-semibold text-slate-950">
                            {availableShiftLabel}
                          </span>
                        </div>
                        <div className="flex items-start justify-between gap-4">
                          <span className="text-slate-500">Rule absensi</span>
                          <span className="text-right font-semibold text-slate-950">
                            {roster
                              ? `${roster.windowBeforeMinutes} menit sebelum s/d ${roster.windowAfterMinutes} menit sesudah shift`
                              : '—'}
                          </span>
                        </div>
                        <div className="flex items-start justify-between gap-4">
                          <span className="text-slate-500">Denda telat</span>
                          <span className="text-right font-semibold text-slate-950">
                            {formatCurrency(roster?.latePenaltyPerMinute)} / menit
                          </span>
                        </div>
                      </div>
                    </div>

                    <div className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
                      <div className="flex items-center gap-2 text-slate-900">
                        <BaseIcon path={officeIcon} size={20} className="text-teal-600" />
                        <h4 className="text-lg font-semibold">Shift aktif / shift berikutnya</h4>
                      </div>
                      <div className="mt-4 space-y-3 text-sm text-slate-600">
                        {roster?.activeShift ? (
                          <>
                            <div className="rounded-2xl border border-emerald-200 bg-emerald-50 p-4">
                              <div className="font-semibold text-emerald-700">
                                Shift aktif sekarang: {roster.activeShift.label}
                              </div>
                              <div className="mt-2 text-emerald-700">
                                Window: {roster.activeShift.windowLabel}
                              </div>
                              <div className="mt-1 text-emerald-700">
                                Status saat submit: {roster.activeShift.status} • estimasi telat{' '}
                                {roster.activeShift.lateMinutes} menit
                              </div>
                            </div>
                          </>
                        ) : roster?.nextShift ? (
                          <div className="rounded-2xl border border-amber-200 bg-amber-50 p-4 text-amber-800">
                            <div className="font-semibold">Belum masuk window shift.</div>
                            <div className="mt-2">
                              Shift terdekat: {roster.nextShift.label} • window {roster.nextShift.windowLabel}
                            </div>
                          </div>
                        ) : (
                          <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4 text-slate-600">
                            Tidak ada shift aktif saat ini.
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                </div>
              </CardBox>

              <CardBox>
                <div className="space-y-6">
                  <div className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
                    <div className="flex items-start justify-between gap-4">
                      <div>
                        <div className="flex items-center gap-2 text-slate-900">
                          <BaseIcon path={gpsIcon} size={20} className="text-teal-600" />
                          <h4 className="text-lg font-semibold">GPS browser</h4>
                        </div>
                        <p className="mt-2 text-sm text-slate-500">
                          Halaman ini akan mencoba mengambil GPS otomatis. Kalau browser HP memblokir,
                          Anda masih bisa isi koordinat manual untuk testing dev.
                        </p>
                      </div>
                      <BaseButton
                        color="info"
                        icon={refreshIcon}
                        label={isLocating ? 'Mengambil GPS…' : 'Ambil GPS lagi'}
                        onClick={() => {
                          void requestLocation();
                        }}
                        disabled={isLocating}
                      />
                    </div>

                    <div className="mt-4 grid gap-4 md:grid-cols-2">
                      <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4">
                        <div className="text-sm font-medium text-slate-500">Latitude</div>
                        <div className="mt-2 text-lg font-semibold text-slate-900">
                          {location?.latitude ?? '—'}
                        </div>
                      </div>
                      <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4">
                        <div className="text-sm font-medium text-slate-500">Longitude</div>
                        <div className="mt-2 text-lg font-semibold text-slate-900">
                          {location?.longitude ?? '—'}
                        </div>
                      </div>
                    </div>

                    <div className="mt-3 text-sm text-slate-500">
                      {location
                        ? `Diambil ${formatDateTime(location.capturedAt)}${
                            location.accuracy ? ` • akurasi ±${Math.round(location.accuracy)} m` : ''
                          }`
                        : 'Belum ada GPS yang berhasil diambil.'}
                    </div>

                    {locationError ? (
                      <div className="mt-4 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
                        {locationError}
                      </div>
                    ) : null}

                    {locationError ? (
                      <div className="mt-4 grid gap-4 md:grid-cols-2">
                        <div>
                          <label className="mb-2 block text-sm font-medium text-slate-700" htmlFor="manualLatitude">
                            Latitude manual
                          </label>
                          <input
                            id="manualLatitude"
                            type="number"
                            step="any"
                            className={inputClassName}
                            value={manualLatitude}
                            onChange={(event) => setManualLatitude(event.target.value)}
                            placeholder="-6.200000"
                          />
                        </div>
                        <div>
                          <label className="mb-2 block text-sm font-medium text-slate-700" htmlFor="manualLongitude">
                            Longitude manual
                          </label>
                          <input
                            id="manualLongitude"
                            type="number"
                            step="any"
                            className={inputClassName}
                            value={manualLongitude}
                            onChange={(event) => setManualLongitude(event.target.value)}
                            placeholder="106.816666"
                          />
                        </div>
                      </div>
                    ) : null}
                  </div>

                  <div className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
                    <div className="flex items-center gap-2 text-slate-900">
                      <BaseIcon path={selfieIcon} size={20} className="text-teal-600" />
                      <h4 className="text-lg font-semibold">Foto selfie</h4>
                    </div>
                    <p className="mt-2 text-sm text-slate-500">
                      Di HP, tombol ini akan membuka kamera depan kalau browser mendukung capture &quot;user&quot;.
                    </p>

                    <div className="mt-4 space-y-4">
                      <input
                        id="clockInSelfie"
                        type="file"
                        accept="image/*"
                        capture="user"
                        className={inputClassName}
                        onChange={handleFileChange}
                      />

                      {selectedFile ? (
                        <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4">
                          <div className="text-sm font-medium text-slate-700">File siap diunggah</div>
                          <div className="mt-1 text-sm text-slate-500">{selectedFile.name}</div>
                          {previewUrl ? (
                            <img
                              src={previewUrl}
                              alt="Preview selfie check in"
                              className="mt-4 h-56 w-full rounded-2xl object-cover"
                            />
                          ) : null}
                        </div>
                      ) : (
                        <div className="rounded-2xl border border-dashed border-slate-300 bg-slate-50 px-4 py-8 text-center text-sm text-slate-500">
                          Belum ada foto selfie yang dipilih.
                        </div>
                      )}
                    </div>
                  </div>

                  <div>
                    <label className="mb-2 block text-sm font-medium text-slate-700" htmlFor="remarks">
                      Catatan opsional
                    </label>
                    <textarea
                      id="remarks"
                      rows={4}
                      className={inputClassName}
                      value={remarks}
                      onChange={(event) => setRemarks(event.target.value)}
                      placeholder="Contoh: buka outlet pagi, bantu stock opname, dsb."
                    />
                  </div>

                  {submitError ? (
                    <div className="rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
                      {submitError}
                    </div>
                  ) : null}

                  <BaseButtons type="justify-start" mb="mb-0" classAddon="mr-3 mb-3 last:mr-0">
                    <BaseButton
                      color="info"
                      icon={pageIcon}
                      label={
                        isSubmitting
                          ? 'Menyimpan clock in…'
                          : hasClockedIn
                            ? 'Sudah clock in hari ini'
                            : 'Clock in sekarang'
                      }
                      onClick={() => {
                        void handleClockIn();
                      }}
                      disabled={
                        isSubmitting ||
                        isLoadingContext ||
                        hasClockedIn ||
                        Boolean(context?.setupError) ||
                        Boolean(context?.clockInBlockedReason && !context?.canClockIn)
                      }
                    />
                    <BaseButton
                      color="white"
                      icon={refreshIcon}
                      label="Refresh context"
                      onClick={() => {
                        void loadClockInContext();
                      }}
                      disabled={isLoadingContext}
                    />
                  </BaseButtons>
                </div>
              </CardBox>
            </div>

            <div className="space-y-6">
              <CardBox>
                <div className="space-y-5">
                  <div>
                    <div className="text-sm font-medium text-slate-500">Checklist sebelum submit</div>
                    <h3 className="mt-1 text-xl font-semibold text-slate-900">Validasi cepat</h3>
                  </div>

                  <div className="space-y-3">
                    {checklistItems.map((item) => (
                      <div
                        key={item.label}
                        className="flex items-center justify-between rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3"
                      >
                        <span className="text-sm text-slate-700">{item.label}</span>
                        <span
                          className={`inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs font-semibold ${getChecklistBadgeClasses(
                            item.ok,
                          )}`}
                        >
                          <BaseIcon path={item.ok ? successIcon : warningIcon} size={16} />
                          {item.ok ? 'OK' : 'Perlu aksi'}
                        </span>
                      </div>
                    ))}
                  </div>
                </div>
              </CardBox>

              <CardBox>
                <div className="space-y-4">
                  <div>
                    <div className="text-sm font-medium text-slate-500">Ringkasan absensi hari ini</div>
                    <h3 className="mt-1 text-xl font-semibold text-slate-900">Record attendance</h3>
                  </div>

                  {isLoadingContext ? (
                    <div className="rounded-2xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-500">
                      Memuat context clock in…
                    </div>
                  ) : todayLog ? (
                    <div className="space-y-3 rounded-2xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-700">
                      <div>
                        <span className="font-medium">ID:</span> {todayLog.id}
                      </div>
                      <div>
                        <span className="font-medium">Check in:</span> {formatDateTime(todayLog.check_in_at)}
                      </div>
                      <div>
                        <span className="font-medium">Status:</span> {todayLog.status || '—'}
                      </div>
                      <div>
                        <span className="font-medium">Late minutes:</span> {lateMinutes}
                      </div>
                      <div>
                        <span className="font-medium">Shift:</span> {roster?.assignedShift?.label || '—'}
                      </div>
                      <div>
                        <span className="font-medium">GPS:</span>{' '}
                        {todayLog.check_in_lat !== null && todayLog.check_in_lng !== null
                          ? `${todayLog.check_in_lat}, ${todayLog.check_in_lng}`
                          : 'Belum ada'}
                      </div>
                    </div>
                  ) : (
                    <div className="rounded-2xl border border-dashed border-slate-200 bg-slate-50 p-5 text-sm text-slate-500">
                      Belum ada record absensi untuk hari ini.
                    </div>
                  )}
                </div>
              </CardBox>

              <CardBox>
                <div className="space-y-4 rounded-2xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-600">
                  <div className="font-medium text-slate-700">Catatan implementasi roster otomatis</div>
                  <ul className="list-disc space-y-2 pl-5">
                    <li>Shift diambil otomatis dari job position/divisi user login.</li>
                    <li>Format jadwal shift per divisi: contoh <span className="font-medium">07:00, 12:00, 15:00</span>.</li>
                    <li>Clock in hanya valid dalam window 60 menit sebelum sampai 60 menit sesudah shift.</li>
                    <li>Keterlambatan otomatis dihitung dari selisih waktu check in terhadap jam shift.</li>
                    <li>Denda telat mengikuti rule <span className="font-medium">Rp1.000 per menit</span>.</li>
                    <li>Validasi radius outlet dan flow clock-out otomatis bisa ditambah di step berikutnya.</li>
                  </ul>
                </div>
              </CardBox>
            </div>
          </div>
        </div>
      </SectionMain>
    </>
  );
};

ClockInPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated permission="CREATE_ATTENDANCE_LOGS">{page}</LayoutAuthenticated>;
};

export default ClockInPage;
