import { world, system } from "@minecraft/server";
import {
  ActionFormData,
  ModalFormData,
} from "@minecraft/server-ui";

// --- UI DEFINITIONS ---
const clvrhorseguidebookui = new ActionFormData()
  .title("Horse Ranch Guides:")
  .body("Which guide book would you like to read?")
  .button("Horse Guide")
  .button("Building Guide")
  .button("Player Guide")
  .button("Vehicles Guide")
  .button("Pick up the Guide Book");

const clvrhorsewagonui = new ActionFormData()
  .title("Horse Ranch Wagon Settings:")
  .button("Enable Connection")
  .button("Disable Connection")
  .button("Change Cosmetics")
  .button("Despawn Wagon");

const clvrhorsestoragewagoncosmeticsui = new ModalFormData()
  .title("Horse Ranch Wagon Cosmetics")
  .dropdown("Select Wagon Roof", ["Don't Change", "No Roof", "Fabric Roof"], 0)
  .dropdown("Select Wagon Contents", ["Don't Change", "Empty", "Hay", "Logs"], 0);

const clvrhorserideablewagoncosmeticsui = new ModalFormData()
  .title("Horse Ranch Wagon Cosmetics")
  .dropdown("Select Wagon Roof", ["Don't Change", "No Roof", "Fabric Roof"], 0)
  .dropdown("Select Wagon Seat Style", ["Don't Change", "Benches", "Haybales"], 0);

// --- TAGS ---
const WAGON_IS_SEEKING_TAG = "clvr_horse_wagon_is_seeking";
const ATTACHED_TAG = "clvr_horse_attached";
const RIDING_WAGON_TAG = "clvr_horse_is_riding_wagon";
const BABY_HORSE_TAG = "clvr_horse_baby";

// --- HORSE CONVERSION LOGIC (For updating old horses) ---
const horseBreeds = [
  "clvr_horse:americanpaint",
  "clvr_horse:arabian",
  "clvr_horse:quarterhorse",
  "clvr_horse:appaloosa",
  "clvr_horse:clydesdale",
  "clvr_horse:friesian",
  "clvr_horse:lipizzan",
  "clvr_horse:tennessee",
  "clvr_horse:thoroughbred",
];

world.afterEvents.entityLoad.subscribe((event) => {
  const { entity } = event;
  if (horseBreeds.includes(entity.typeId) && !entity.hasTag("clvr_horse_v14")) {
    if (!entity.hasComponent("minecraft:is_baby")) {
      entity.runCommand("event entity @s cleverlike:addhitchedseat");
      entity.runCommand("event entity @s cleverlike:removehitchedseat");
    }
    entity.addTag("clvr_horse_v14");
  }
});


// --- ENTITY INTERACTION LOGIC ---
world.afterEvents.entityHitEntity.subscribe((event) => {
  const { hitEntity, damagingEntity } = event;
  if (damagingEntity.typeId !== "minecraft:player") return;
  const player = damagingEntity;

  try {
    // Guidebook Logic
    if (hitEntity.typeId === "clvr_horse:tutbook") {
      clvrhorseguidebookui.show(player).then((response) => {
        if (response.canceled) return;
        if (response.selection === 0) hitEntity.runCommand("event entity @s cleverlike:book1");
        if (response.selection === 1) hitEntity.runCommand("event entity @s cleverlike:book3");
        if (response.selection === 2) hitEntity.runCommand("event entity @s cleverlike:book2");
        if (response.selection === 3) hitEntity.runCommand("event entity @s cleverlike:book4");
        if (response.selection === 4) {
          player.runCommand("give @s clvr_horse:tutbook_spawn_egg");
          hitEntity.runCommand("event entity @s e_despawn");
        }
      });
    }

    // Wagon Logic
    if (hitEntity.typeId.includes("wagon")) {
      clvrhorsewagonui.show(player).then((response) => {
        if (response.canceled) return;
        const wagon = hitEntity;

        if (response.selection === 0) { // Enable Connection
          wagon.addTag(WAGON_IS_SEEKING_TAG);
          wagon.runCommand("event entity @s e_attachable");
        }

        if (response.selection === 1) { // Detach
          wagon.removeTag(WAGON_IS_SEEKING_TAG);
          wagon.runCommand("event entity @s e_unattachable");
          wagon.runCommand("ride @s stop_riding");
        }

        // Button 2: Change Cosmetics
        if (response.selection === 2) {
          if (hitEntity.typeId === "clvr_horse:wagon") {
            clvrhorsestoragewagoncosmeticsui.show(player).then((res) => {
              if (res.canceled) return;
              if (res.formValues[0] === 1) hitEntity.runCommand("event entity @s cleverlike:roofoff");
              if (res.formValues[0] === 2) hitEntity.runCommand("event entity @s cleverlike:roofon");
              if (res.formValues[1] === 1) hitEntity.runCommand("event entity @s cleverlike:internaloff");
              if (res.formValues[1] === 2) hitEntity.runCommand("event entity @s cleverlike:internal1");
              if (res.formValues[1] === 3) hitEntity.runCommand("event entity @s cleverlike:internal2");
            });
          } else if (hitEntity.typeId === "clvr_horse:rideablewagon") {
            clvrhorserideablewagoncosmeticsui.show(player).then((res) => {
              if (res.canceled) return;
              if (res.formValues[0] === 1) hitEntity.runCommand("event entity @s cleverlike:roofoff");
              if (res.formValues[0] === 2) hitEntity.runCommand("event entity @s cleverlike:roofon");
              if (res.formValues[1] === 1) hitEntity.runCommand("event entity @s cleverlike:seatson");
              if (res.formValues[1] === 2) hitEntity.runCommand("event entity @s cleverlike:seatshay");
            });
          }
        }

        if (response.selection === 3) { // Despawn
          if (hitEntity.typeId === "clvr_horse:wagon") player.runCommand("give @s clvr_horse:wagon_spawn_egg");
          if (hitEntity.typeId === "clvr_horse:rideablewagon") player.runCommand("give @s clvr_horse:rideablewagon_spawn_egg");
          hitEntity.runCommand("event entity @s e_despawn");
        }
      });
    }
  } catch (e) { console.error(e, e.stack); }
});


// --- MAIN LOGIC LOOP ---
system.runInterval(() => {
  const allCurrentRiders = new Set();

  const playersRidingWagons = new Set();

  const allWagonsNearPlayers = new Map();
  try {
    // --- Connection Logic ---
    const seekingWagons = world.getDimension("overworld").getEntities({ tags: [WAGON_IS_SEEKING_TAG] });

    for (const wagon of seekingWagons) {
      if (!wagon.isValid()) continue;

      const ridingComp = wagon.getComponent("minecraft:riding");
      if (ridingComp && ridingComp.entity) {
        wagon.removeTag(WAGON_IS_SEEKING_TAG);
        continue;
      }

      const nearbyHorses = wagon.dimension.getEntities({
        location: wagon.location,
        maxDistance: 3,
        families: ["clvr_horse"],
        excludeTags: [ATTACHED_TAG]
      });

      const adultHorse = nearbyHorses.find(horse => !horse.hasComponent('minecraft:is_baby'));

      if (adultHorse) {
        adultHorse.runCommandAsync("event entity @s cleverlike:addhitchedseat");
        adultHorse.runCommandAsync("event entity @s cleverlike:haswagonrider");
        wagon.runCommandAsync(`ride @s start_riding @e[type=${adultHorse.typeId},c=1,r=5]`);
      }
    }

    // --- Delayed State & Cleanup Logic ---
    system.runTimeout(() => {
      for (const horse of world.getDimension("overworld").getEntities({ families: ["clvr_horse"] })) {
        if (!horse.isValid()) continue;

        const rideable = horse.getComponent("minecraft:rideable");
        if (!rideable) continue;

        const wagonRider = rideable.getRiders().find(rider => rider.typeId.includes("wagon"));

        if (wagonRider) {
          horse.addTag(ATTACHED_TAG);
          if (wagonRider.isValid() && wagonRider.hasTag(WAGON_IS_SEEKING_TAG)) {
            wagonRider.removeTag(WAGON_IS_SEEKING_TAG);
          }
          if (wagonRider.isValid()) {
            const velocity = horse.getVelocity();
            const speed = Math.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
            wagonRider.setProperty("cleverlike:wheel_speed", Math.min(speed * 30, 5.0));
          }
        } else {
          if (horse.hasTag(ATTACHED_TAG)) {
            horse.removeTag(ATTACHED_TAG);
            horse.runCommandAsync("event entity @s cleverlike:hasntwagonrider");
            horse.runCommandAsync("event entity @s cleverlike:hasntwagonrider");
          }
        }
      }
    }, 1);

    // --- Camera & Invisibility Logic ---
    world.getPlayers().forEach((player) => {
      // Get all horses near the player to check who is riding them.
      const rideableHorses = player.dimension.getEntities({
        location: player.location,
        maxDistance: 100,
        families: ["clvr_horse"],
      });

      // Build a master list of all current riders.
      for (const horse of rideableHorses) {
        const rideable = horse.getComponent("minecraft:rideable");
        if (rideable) {
          for (const rider of rideable.getRiders()) {
            allCurrentRiders.add(rider.id);
          }
        }

        if (horse.hasComponent('minecraft:is_baby')) {
                // First, do the one-time setup to prevent visual flashing.
                if (!horse.hasTag(BABY_HORSE_TAG)) {
                    horse.addTag(BABY_HORSE_TAG);
                    horse.runCommandAsync("event entity @s cleverlike:staybaby");
                }

                // NEW: Constantly check for any unwanted riders.
                const babyrideable = horse.getComponent("minecraft:rideable");
                if (babyrideable && babyrideable.getRiders().length > 0) {
                    // If a rider is detected, run the event again to forcefully dismount them.
                    horse.runCommandAsync("event entity @s cleverlike:staybaby");
                }
                
                continue; // Always skip the rest of the logic for babies.
            } else {
                // If it's an adult, ensure the baby tag is removed.
                horse.removeTag(BABY_HORSE_TAG);
            }
      }

      // Get all wagons near the player to check their state.
      const nearbyWagons = player.dimension.getEntities({
        location: player.location,
        maxDistance: 100,
        families: ["wagon"],
      });



      // Add wagons to a map to check them for cleanup.
      for (const wagon of nearbyWagons) {
        allWagonsNearPlayers.set(wagon.id, wagon);
        const rideable = wagon.getComponent("minecraft:rideable");
        if (rideable) {
          const riders = rideable.getRiders();
          for (const rider of riders) {
            if (rider.typeId === "minecraft:player") {
              playersRidingWagons.add(rider.id);
            }
          }
        }
      }

      if (playersRidingWagons.has(player.id)) {
        player.runCommand("camera @s set minecraft:third_person");
        player.addTag("riding_wagon");
      } else {
        // This will remove the tag if you get off the wagon.
        player.runCommand("execute as @s[tag=riding_wagon] run camera @s clear");
        player.removeTag("riding_wagon");
      }

      // This new loop ensures any un-hitched wagon has its wheels stopped.
      for (const wagon of world.getDimension("overworld").getEntities({ families: ["wagon"] })) {
        if (!wagon.isValid()) continue;

        const ridingComp = wagon.getComponent("minecraft:riding");
        // If the wagon is NOT riding anything, set its wheel speed to 0.
        if (!ridingComp || !ridingComp.entity) {
          wagon.setProperty("cleverlike:wheel_speed", 0.0);
        }
      }
    })
  } catch (e) { console.error(e, e.stack); }
});