-- Trigger to replicate attendance_check_in RPC side-effects when a new
-- attendance_log row is inserted directly (e.g. from Brick's offline queue
-- after sync). The RPC path is unchanged; this trigger only fires on plain
-- INSERT and is a no-op when the RPC already handled the duty_schedule update
-- (idempotent: ON CONFLICT (id) DO NOTHING is handled by Brick).
--
-- Side-effects replicated from attendance_check_in RPC:
--   1. duty_schedules.check_in_at   ← attendance_log.check_in_at
--   2. duty_schedules.check_in_location ← lat/lng
--   3. duty_schedules.status        ← 'arrival' if on time, 'late' if past start
--
-- For check-out, the trigger replicates attendance_check_out side-effects:
--   1. duty_schedules.check_out_at  ← attendance_log.check_out_at
--   2. duty_schedules.check_out_location ← lat/lng
--   3. duty_schedules.status        ← 'completed'

CREATE OR REPLACE FUNCTION public.attendance_log_after_upsert()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
  v_schedule duty_schedules%ROWTYPE;
BEGIN
  -- Skip if we have no duty_schedule_id (shouldn't happen, but be defensive)
  IF NEW.duty_schedule_id IS NULL THEN
    RETURN NEW;
  END IF;

  SELECT * INTO v_schedule FROM duty_schedules WHERE id = NEW.duty_schedule_id;
  IF NOT FOUND THEN
    RETURN NEW;
  END IF;

  -- ── Check-in side-effects ────────────────────────────────────────────────
  -- Only apply when check_in_at changed or this is a new row.
  IF (TG_OP = 'INSERT') OR
     (TG_OP = 'UPDATE' AND
      (OLD.check_in_at IS DISTINCT FROM NEW.check_in_at OR
       OLD.check_in_lat IS DISTINCT FROM NEW.check_in_lat)) THEN

    -- Skip if duty_schedules already has a check_in_at (RPC already ran)
    IF v_schedule.check_in_at IS NULL THEN
      UPDATE duty_schedules
      SET
        check_in_at       = NEW.check_in_at,
        check_in_location = jsonb_build_object(
                              'latitude',  NEW.check_in_lat,
                              'longitude', NEW.check_in_lng
                            ),
        status            = CASE
                              WHEN NEW.check_in_at <= v_schedule.start_time
                              THEN 'arrival'
                              ELSE 'late'
                            END
      WHERE id = NEW.duty_schedule_id;
    END IF;
  END IF;

  -- ── Check-out side-effects ───────────────────────────────────────────────
  IF NEW.check_out_at IS NOT NULL AND
     (TG_OP = 'INSERT' OR OLD.check_out_at IS DISTINCT FROM NEW.check_out_at) THEN

    UPDATE duty_schedules
    SET
      check_out_at       = NEW.check_out_at,
      check_out_location = jsonb_build_object(
                             'latitude',  NEW.check_out_lat,
                             'longitude', NEW.check_out_lng
                           ),
      status             = 'completed'
    WHERE id = NEW.duty_schedule_id
      AND check_out_at IS NULL; -- idempotent: only if not already checked out
  END IF;

  RETURN NEW;
END;
$$;

-- Fire AFTER INSERT and AFTER UPDATE so both offline-queued inserts and
-- subsequent Brick upserts (when check_out_at is filled in) are handled.
DROP TRIGGER IF EXISTS attendance_logs_after_upsert ON attendance_logs;
CREATE TRIGGER attendance_logs_after_upsert
  AFTER INSERT OR UPDATE ON attendance_logs
  FOR EACH ROW
  EXECUTE FUNCTION public.attendance_log_after_upsert();
