package dev.ksan.etfoglasiserver.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import dev.ksan.etfoglasiserver.model.Entry;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;


import dev.ksan.etfoglasiserver.model.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;


@Component
public class Scraper implements Runnable {

  @Autowired SubjectAltService altService;
  @Autowired EntryService entryService;

  private static final String BASE_URL = "https://efee.etf.unibl.org:8443";

  private static final List<Integer> BOARD_IDS = List.of(1, 2, 3, 4, 20, 21, 30, 102);

  private final RestTemplate restTemplate;
  private final ObjectMapper objectMapper;
  private volatile boolean running = true;

  DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

  public Scraper() {
    this.restTemplate = new RestTemplate();
    this.objectMapper = new ObjectMapper();
  }

  @Override
  public void run() {
    while (running && !Thread.currentThread().isInterrupted()) {
      try {
        System.out.println("Fetching announcements via API...");

        for (int boardId : BOARD_IDS) {
          fetchAndProcessBoard(boardId);
        }

        Thread.sleep(600000);

      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        System.out.println("Scraper interrupted");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    System.out.println("Scraper thread stopped");
  }

  private void fetchAndProcessBoard(int boardId) {
    try {
      String url = BASE_URL + "/api/public/oglasne-ploce/" + boardId;
      ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);



      if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null) {
        System.out.println("No data for board " + boardId);
        return;
      }

      JsonNode root = objectMapper.readTree(response.getBody());

      // Handle both array response and single object
      Iterable<JsonNode> items = root.isArray() ? root : List.of(root);

      for (JsonNode item : items) {
        processAnnouncement(item);
      }

    } catch (Exception e) {
      System.err.println("Failed to fetch board " + boardId + ": " + e.getMessage());
    }
  }

  private void processAnnouncement(JsonNode item) {
    try {
      String title    = textOrEmpty(item, "naslov");
      String uvod     = textOrEmpty(item, "uvod");
      String sadrzaj  = textOrEmpty(item, "sadrzaj");
      String potpis   = textOrEmpty(item, "potpis");
      String created  = textOrEmpty(item, "vrijemeKreiranja");

      // Board name maps to your old "groupName"
      String groupName = "";
      JsonNode board = item.get("oglasnaPloca");
      if (board != null && !board.isNull()) {
        groupName = textOrEmpty(board, "naziv");
      }

      // Attachments (filepath)
      String filepath = null;
      JsonNode prilozi = item.get("oglasPrilozi");
      if (prilozi != null && prilozi.isArray() && !prilozi.isEmpty()) {
        filepath = textOrEmpty(prilozi.get(0), "putanja"); // adjust field name
      }

      LocalDateTime dateTime = created.isEmpty()
              ? LocalDateTime.now()
              : LocalDateTime.parse(created, formatter);

      // Combine uvod + sadrzaj as paragraphs (mirrors old <p> tags)
      List<String> paragraphs = new ArrayList<>();
      if (!uvod.isEmpty())    paragraphs.add(uvod);
      if (!sadrzaj.isEmpty()) paragraphs.add(sadrzaj);
      if (!potpis.isEmpty())  paragraphs.add(potpis);

      Subject subject = altService.findSubjectIdWithTitle(title);
      Entry entry = new Entry(
              title.trim(), groupName, dateTime,
              uvod, paragraphs, filepath, subject
      );

      System.out.println("Entry: " + entry.getTitle());
      entryService.addEntry(entry);

    } catch (Exception e) {
      System.err.println("Failed to process announcement: " + e.getMessage());
    }
  }

  private static String textOrEmpty(JsonNode node, String field) {
    JsonNode value = node.get(field);
    return (value == null || value.isNull()) ? "" : value.asText();
  }

  public void stop() {
    running = false;
  }
}

