<?php

namespace GemBoards\API;

use GemBoards\Utils\Helper;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class Cards extends WP_REST_Controller {

	public static function init() {
		$self            = new self();
		$self->namespace = 'gemboards/v1';
		$self->rest_base = 'cards';
		add_action( 'rest_api_init', [ $self, 'register_routes' ] );
	}

	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/(?P<id>\d+)',
			[
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => [ $this, 'get_item' ],
				'permission_callback' => [ $this, 'can_view_card' ],
				'args'                => [
					'id' => [
						'type'        => 'integer',
						'required'    => true,
						'description' => __( 'Card ID', 'gemboards' ),
					],
				],
			]
		);
	}

	public function can_view_card( WP_REST_Request $request ): bool {
		if ( ! current_user_can('read') ) {
			return false;
		}

		if ( current_user_can( 'manage_gemboards' ) ) {
			return true;
		}

		$user_id      = get_current_user_id();
		$card_id      = $request->get_param( 'id' );
		$cache_group  = 'gemboards_roles';
		$last_changed = wp_cache_get_last_changed( $cache_group );
		$cache_key    = "role_by_user_{$user_id}_card_$card_id:$last_changed";

		$has_cache = wp_cache_get( $cache_key, $cache_group );
		if ( $has_cache ) {
			return (bool) $has_cache;
		}

		global $wpdb;
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
		$result = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT
							card.id as card_id
						FROM
							{$wpdb->prefix}gemboards_cards card
							INNER JOIN {$wpdb->prefix}gemboards_boards board ON board.id = card.board_id
							INNER JOIN {$wpdb->prefix}gemboards_roles role ON role.object_id = board.project_id
							AND role.object_type = 'project'
							AND role.user_id = %d
						WHERE
							card.id = %d", $user_id, $card_id
			)
		);
		// phpcs:enable

		wp_cache_set( $cache_key, $result, $cache_group );

		return (bool) $result;
	}

	/**
	 * Retrieves one item from the collection.
	 *
	 * @param WP_REST_Request $request Full details about the request.
	 *
	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
	 */
	public function get_item( $request ) {
		$id = $request->get_param( 'id' );
		if ( ! $id ) {
			return new WP_Error(
				'rest_invalid_param',
				__( 'Invalid Card ID.', 'gemboards' ),
				[
					'status' => 400,
					'params' => [ 'id' ],
				]
			);
		}

		$card = Helper::get_card( $id );
		if ( ! $card ) {
			return new WP_Error(
				'rest_invalid_param',
				__( 'Invalid Card ID.', 'gemboards' ),
				[
					'status' => 400,
					'params' => [ 'id' ],
				]
			);
		}

		$task_id = $card->get_task_id();
		$task    = $card->get_task();
		if ( ! $task ) {
			return new WP_Error( 'gemboards_task_deleted', __( 'Task not found.', 'gemboards' ), [
				'status' => 400,
				'params' => [ 'id' ],
			] );
		}

		$priority = null;
		$labels   = [];

		$terms = wp_get_object_terms(
			$task_id,
			[ 'gemboards_label', 'gemboards_priority' ],
		);
		foreach ( $terms as $term ) {
			if ( 'gemboards_label' === $term->taxonomy ) {
				$labels[] = [
					'id'         => $term->term_id,
					'name'       => $term->name,
					'slug'       => $term->slug,
					'bg_color'   => get_term_meta( $term->term_id, 'bg_color', true ) ?: '#cccccc',
					'text_color' => get_term_meta( $term->term_id, 'text_color', true ) ?: '#000000',
				];
			} else {
				$priority = [
					'id'   => $term->term_id,
					'name' => $term->name,
					'slug' => $term->slug,
				];
			}
		}

		$attachments = array_map( function ( $attachment ) {
			return [
				'id'        => $attachment->get_id(),
				'file_url'  => $attachment->get_file_url(),
				'file_name' => $attachment->get_file_name(),
				'file_type' => $attachment->get_file_type(),
				'file_size' => $attachment->get_file_size(),
				'date'      => $attachment->get_date_created_at(),
			];
		}, $card->get_attachments() );

		$assignee_list = array_map( function ( $assignee ) {
			return [
				'id'     => $assignee->get_user_id(),
				'name'   => get_the_author_meta( 'display_name', $assignee->get_user_id() ),
				'avatar' => get_avatar_url( $assignee->get_user_id(), [ 'size' => 96 ] ),
			];
		}, $card->get_assignees() );

		$checklist_groups = [];
		foreach ( $card->get_checklist_groups() as $checklist_group ) {
			$checklist_groups[ $checklist_group->get_id() ] = [
				'id'      => $checklist_group->get_id(),
				'task_id' => $task_id,
				'card_id' => $checklist_group->get_card_id(),
				'label'   => $checklist_group->get_label(),
				'items'   => [],
			];
		}

		$checklist_items = $card->get_checklists();
		foreach ( $checklist_items as $checklist_item ) {
			$checklist_groups[ $checklist_item->get_checklist_group_id() ]['items'][] = array_merge( $checklist_item->get_data(), [
				'id'         => $checklist_item->get_id(),
				'created_at' => $checklist_item->get_date_created_at() ? $checklist_item->get_date_created_at()->format( 'Y-m-d H:i:s' ) : null,
				'updated_at' => $checklist_item->get_date_updated_at() ? $checklist_item->get_date_updated_at()->format( 'Y-m-d H:i:s' ) : null,
			] );
		}

		$custom_fields = [];
		foreach ( $card->get_custom_fields() as $custom_field ) {
			$custom_fields[] = array_merge( $custom_field->get_data(), [
				'id'    => $custom_field->get_id(),
				'value' => get_post_meta($card->get_task_id(), "_gemboards_pro_custom_field_{$custom_field->get_id()}", true),
			]);
		}

		$comment_data = array_map( function ( $comment ) {
			return [
				'id'        => absint($comment->comment_ID),
				'user_id'   => absint($comment->user_id),
				'content'   => $comment->comment_content,
				'date_time' => get_comment_date( 'Y-m-d H:i', $comment ),
				'author'    => $comment->comment_author,
				'avatar'    => get_avatar_url( $comment->user_id, [ 'size' => 96 ] ),
			];
		}, Helper::get_card_comments( $task_id ) );

		$activity_data = array_map( function ( $comment ) {
			return [
				'id'        => (int) $comment->comment_ID,
				'content'   => $comment->comment_content,
				'date_time' => get_comment_date( 'Y-m-d H:i', $comment ),
				'author'    => $comment->comment_author,
				'avatar'    => get_avatar_url( $comment->user_id, [ 'size' => 96 ] ),
			];
		}, Helper::get_card_activities( $task_id ) );

		$card_author = get_user( $task->post_author );

		return rest_ensure_response(
			apply_filters('gemboards/api/single_card_response', [
				'id'             => $card->get_id(),
				'column_id'      => $card->get_column_id(),
				'board_id'       => $card->get_board_id(),
				'task_id'        => $card->get_task_id(),
				'sprint_id'      => $card->get_sprint_id(),
				'parent_task_id' => $task->post_parent,
				'title'          => $task->post_title,
				'description'    => wp_kses_post( $task->post_content ),
				'sort_order'     => $card->get_sort_order(),
				'story_point'    => $card->get_story_point(),
				'due_date'       => $card->get_due_date() ? $card->get_due_date()->format( 'Y-m-d' ) : null,
				'assignees'      => $assignee_list,
				'comments'       => $comment_data,
				'activity'       => $activity_data,
				'priority'       => $priority,
				'labels'         => $labels,
				'attachments'    => $attachments,
				'checklists'     => array_values( $checklist_groups ),
				'custom_fields' => $custom_fields,
				'created_by'     => [
					'display_name' => $card_author->display_name,
					'username'     => $card_author->user_login,
					'avatar'       => get_avatar_url( $card_author->ID ),
					'id'           => $card_author->ID,
				],
			])
		);
	}
}
