#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../include/chroma.h"

void chroma_transition_init_output(chroma_output_t *output, int duration_ms) {
  if (!output) {
    return;
  }

  if (duration_ms <= 0) {
    chroma_log("DEBUG", "Transition skipped for output %u: duration_ms=%d",
               output->id, duration_ms);
    return;
  }

  output->transition_duration_ms = duration_ms;
  output->transition_start_ms = chroma_get_time_ms();
  output->in_transition = true;

  chroma_log("DEBUG", "Transition started for output %u: %dms", output->id,
             duration_ms);
}

void chroma_transition_cleanup_output(chroma_output_t *output) {
  if (!output) {
    return;
  }

  if (output->transition_prev) {
    free(output->transition_prev);
    output->transition_prev = NULL;
    output->transition_prev_size = 0;
  }

  output->in_transition = false;
  output->transition_start_ms = 0;
}

bool chroma_transition_is_active(chroma_output_t *output) {
  if (!output || !output->in_transition) {
    return false;
  }

  long long now = chroma_get_time_ms();
  long long elapsed = now - output->transition_start_ms;

  if (elapsed >= output->transition_duration_ms) {
    chroma_transition_cleanup_output(output);
    return false;
  }

  return true;
}

float chroma_transition_get_alpha(chroma_output_t *output,
                                  long long current_time_ms) {
  if (!output || !output->in_transition) {
    return 1.0f;
  }

  long long elapsed = current_time_ms - output->transition_start_ms;
  if (elapsed <= 0)
    return 0.0f;
  if (elapsed >= output->transition_duration_ms)
    return 1.0f;

  float alpha = (float)elapsed / (float)output->transition_duration_ms;
  return alpha;
}

bool chroma_transition_needs_redraw(chroma_state_t *state) {
  if (!state) {
    return false;
  }

  for (int i = 0; i < state->output_count; i++) {
    if (chroma_transition_is_active(&state->outputs[i])) {
      return true;
    }
  }

  return false;
}

int chroma_transition_update_outputs(chroma_state_t *state) {
  if (!state) {
    return CHROMA_ERROR_INIT;
  }

  int updated = 0;
  for (int i = 0; i < state->output_count; i++) {
    chroma_output_t *output = &state->outputs[i];
    if (chroma_transition_is_active(output)) {
      int ret = chroma_render_wallpaper(state, output);
      if (ret == CHROMA_OK) {
        updated++;
      }
    }
  }

  if (updated > 0) {
    chroma_log("DEBUG", "Transition frames rendered: %d outputs", updated);
  }

  return CHROMA_OK;
}
