<?php

namespace GemBoards\Ajax;

use GemBoards\Classes\AbstractAjaxHandler;
use GemBoards\Classes\Exception\GemboardsException;
use GemBoards\Entities\TaskAttachment;
use GemBoards\Utils\Helper;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Tasks extends AbstractAjaxHandler {

	public function __construct() {
		$this->actions = [
			'get_dashboard_tasks'    => [
				'callback' => [ $this, 'get_dashboard_tasks' ],
			],
			'add_task_comment'       => [
				'callback'   => [ $this, 'add_task_comment' ],
				'permission' => 'allow_comments',
				'fields'     => [
					'task_id' => 'integer',
					'comment' => 'string',
				],
			],
			'edit_task_comment'      => [
				'callback' => [ $this, 'edit_task_comment' ],
				'fields'   => [
					'comment_id' => 'integer',
					'comment'    => 'string',
				],
			],
			'delete_task_comment'    => [
				'callback' => [ $this, 'delete_task_comment' ],
				'fields'   => [
					'comment_id' => 'integer',
				],
			],
			'upload_task_attachment' => [
				'callback'   => [ $this, 'upload_task_attachment' ],
				'permission' => 'manage_tasks',
				'fields'     => [
					'task_id' => 'integer',
				],
			],
			'delete_task_attachment' => [
				'callback'   => [ $this, 'delete_task_attachment' ],
				'permission' => 'manage_tasks',
				'fields'     => [
					'id'      => 'integer',
					'task_id' => 'integer',
				],
			],
			'update_task_title'      => [
				'callback'   => [ $this, 'update_task_title' ],
				'permission' => 'manage_tasks',
				'fields'     => [
					'task_id' => 'integer',
					'title'   => 'string',
				],
			],
		];
	}

	public function get_dashboard_tasks() {
		$user_id = get_current_user_id();
		$now     = current_time( 'Y-m-d' );

		$cards_last_changed     = wp_cache_get_last_changed( Helper::BOARD_CARD_TABLE_NAME );
		$assignees_last_changed = wp_cache_get_last_changed( Helper::CARD_ASSIGNEES_TABLE_NAME );
		$boards_last_changed    = wp_cache_get_last_changed( Helper::BOARDS_TABLE_NAME );
		$columns_last_changed   = wp_cache_get_last_changed( Helper::BOARD_COLUMN_TABLE_NAME );
		$cache_key              = "dashboard_tasks_{$user_id}:$cards_last_changed:$assignees_last_changed:$boards_last_changed:$columns_last_changed";
		$cache_group            = 'gemboards_dashboard_tasks';
		$has_cache              = wp_cache_get( $cache_key, $cache_group );
		if ( false !== $has_cache ) {
			wp_send_json_success( $has_cache );
		}

		global $wpdb;
		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
		$cards = $wpdb->get_results(
			$wpdb->prepare( "
				SELECT
				  c.id,
				  c.task_id,
				  c.board_id,
				  c.column_id,
				  c.sprint_id,
				  c.sort_order,
				  c.archived,
				  c.due_date,
				  c.is_completed,
				  a.user_id AS ass_user_id,
				  b.id AS board_id,
				  b.title AS board_title,
				  col.id AS column_id,
				  col.title AS column_title
				FROM
				  {$wpdb->prefix}gemboards_cards AS c
				  LEFT JOIN {$wpdb->prefix}gemboards_card_assignees AS a ON a.card_id = c.id
				  LEFT JOIN {$wpdb->prefix}gemboards_boards AS b ON b.id = c.board_id
				  LEFT JOIN {$wpdb->prefix}gemboards_columns AS col ON col.id = c.column_id
				WHERE
				  a.user_id = %d", $user_id )
		);
		// phpcs:enable

		$upcoming    = [];
		$overdue     = [];
		$no_due_date = [];
		$completed   = [];
		foreach ( $cards as $card ) {
			if ( $card->is_completed ) {
				$completed[] = $card;
			} else {
				$due = $card->due_date;
				if ( $due ) {
					if ( $due < $now ) {
						$overdue[] = $card;
					} else {
						$upcoming[] = $card;
					}
				} else {
					$no_due_date[] = $card;
				}
			}
		}

		$response = [
			'upcoming'    => $upcoming,
			'overdue'     => $overdue,
			'no_due_date' => $no_due_date,
			'completed'   => $completed,
		];
		wp_cache_set( $cache_key, $response, $cache_group );

		wp_send_json_success( $response );
	}

	public function add_task_comment( $request ) {
		$task_comment_user_id = get_current_user_id();

		$task_comment_post_id = $request['task_id'] ?? 0;
		$task_comment_content = wp_kses_post( (string) ( $request['comment'] ?? '' ) );
		$task_comment_type    = 'task_comment';

		if ( ! $task_comment_post_id || empty( $task_comment_content ) ) {
			wp_send_json_error( [ 'message' => __( 'task_id & comment required', 'gemboards' ) ], 400 );
		}

		if ( ! get_post( $task_comment_post_id ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid task_id', 'gemboards' ) ], 404 );
		}

		if ( ! comments_open( $task_comment_post_id ) ) {
			wp_send_json_error( [ 'message' => __( 'Comments closed', 'gemboards' ) ], 403 );
		}

		$task_comment_user = get_userdata( $task_comment_user_id );
		$task_comment_id   = wp_insert_comment( [
			'comment_post_ID'      => $task_comment_post_id,
			'comment_content'      => $task_comment_content,
			'user_id'              => $task_comment_user_id,
			'comment_author'       => $task_comment_user->display_name ?? 'User',
			'comment_author_email' => $task_comment_user->user_email ?? '',
			'comment_author_url'   => $task_comment_user->user_url ?? '',
			'comment_type'         => $task_comment_type,
			'comment_approved'     => 1,
			'comment_date'         => current_time( 'mysql' ),
			'comment_date_gmt'     => current_time( 'mysql', true ),
			'comment_agent'        => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '',
			'comment_author_IP'    => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '',
		] );
		if ( ! $task_comment_id ) {
			wp_send_json_error( [ 'message' => __( 'Failed to save', 'gemboards' ) ], 500 );
		}

		$obj = get_comment( $task_comment_id );
		wp_send_json_success( [
			'id'        => $task_comment_id,
			'task_id'   => $task_comment_post_id,
			'user_id'   => $task_comment_user_id,
			'name'      => get_comment_author( $task_comment_id ),
			'avatar'    => get_avatar_url( $task_comment_user_id ),
			'content'   => $obj->comment_content,
			'date'      => $obj->comment_date,
			'type'      => $obj->comment_type,
			'permalink' => get_comment_link( $task_comment_id ),
		] );
	}

	public function edit_task_comment( $request ) {
		$user_id    = get_current_user_id();
		$comment_id = $request['comment_id'] ?? 0;
		if ( ! $comment_id ) {
			wp_send_json_error( [ 'message' => __( 'Comment ID is required.', 'gemboards' ) ], 400 );
		}
		$comment = $request['comment'] ?? '';
		if ( empty( $comment ) ) {
			wp_send_json_error( [ 'message' => __( 'Comment content is required.', 'gemboards' ) ], 400 );
		}

		$existing = get_comment( $comment_id );
		if ( ! $existing ) {
			wp_send_json_error( [ 'message' => __( 'Invalid Comment ID.', 'gemboards' ) ], 404 );
		}
		$task_id = absint( $existing->comment_post_ID );
		if ( ! current_user_can( 'allow_comments', [ 'task_id' => $task_id ] ) ) {
			wp_send_json_error( [ 'message' => __( "You don't have permission to edit comments.", 'gemboards' ) ], 403 );
		}
		if ( absint( $existing->user_id ) !== $user_id ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized to edit this comment.', 'gemboards' ) ], 403 );
		}

		$updated = wp_update_comment( [
			'comment_ID'      => $comment_id,
			'comment_content' => $comment,
		] );

		if ( is_wp_error( $updated ) ) {
			wp_send_json_error( [ 'message' => $updated->get_error_message() ], 500 );
		}

		wp_send_json_success( [
			'id'      => $comment_id,
			'comment' => $comment,
			'date'    => current_time( 'mysql' ),
		] );
	}

	public function upload_task_attachment( $request ) {
		$security = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
		if ( empty( $security ) || ! wp_verify_nonce( $security, 'gemboards_nonce' ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'gemboards' ) ], 400 );
		}

		$user_id = get_current_user_id();
		$task_id = intval( $request['task_id'] );

		if ( ! $task_id ) {
			wp_send_json_error( [ 'message' => __( 'Missing task ID.', 'gemboards' ) ], 400 );
		}

		if ( empty( $_FILES['file'] ) || ! is_array( $_FILES['file'] ) ) {
			wp_send_json_error(
				[ 'message' => __( 'Missing File.', 'gemboards' ) ],
				400
			);
		}

		if ( ! function_exists( 'wp_handle_upload' ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
		}

		$uploaded = wp_handle_upload( $_FILES['file'], [ 'test_form' => false ] );

		if ( isset( $uploaded['error'] ) ) {
			wp_send_json_error( [ 'message' => $uploaded['error'] ], 500 );
		}

		$file_url  = $uploaded['url'];
		$file_path = $uploaded['file'];
		$file_name = basename( $file_path );
		$file_type = wp_check_filetype( $file_path );
		$file_size = filesize( $file_path );

		try {
			$task_attachment = new TaskAttachment();
			$task_attachment->set_task_id( $task_id );
			$task_attachment->set_user_id( $user_id );
			$task_attachment->set_file_url( $file_url );
			$task_attachment->set_file_name( $file_name );
			$task_attachment->set_file_type( $file_type['type'] );
			$task_attachment->set_file_size( $file_size );
			$task_attachment->save();

			wp_send_json_success( [
				'id'        => $task_attachment->get_id(),
				'file_url'  => $file_url,
				'file_name' => $file_name,
				'file_type' => $file_type['type'],
				'file_size' => $file_size,
				'date'      => current_time( 'mysql' ),
			] );
		} catch ( \Exception $e ) {
			wp_send_json_error( [
				'message' => sprintf(
				// translators: %s is the actual error message.
					__( 'Failed to upload: %s', 'gemboards' ), $e->getMessage()
				),
			] );
		}
	}

	public function delete_task_attachment( $request ) {
		if ( ! isset( $request['id'] ) ) {
			wp_send_json_error( [ 'message' => __( 'Task Attachment ID is required.', 'gemboards' ) ], 400 );
		}

		if ( ! isset( $request['task_id'] ) ) {
			wp_send_json_error( [ 'message' => __( 'Task ID is required.', 'gemboards' ) ], 400 );
		}

		$task_attachment = Helper::get_task_attachment( $request['id'] );
		if ( ! $task_attachment ) {
			wp_send_json_error( [
				'message' => __( 'Invalid Task Attachment ID.', 'gemboards' ),
			] );
		}

		try {
			$result = $task_attachment->delete();
			if ( ! $result ) {
				wp_send_json_error( [ 'message' => __( 'Failed to delete attachment.', 'gemboards' ) ] );
			}

			wp_send_json_success( [
				'message' => __( 'Task Attachment successfully deleted.', 'gemboards' ),
			] );
		} catch ( GemboardsException $e ) {
			wp_send_json_error( [ 'message' => $e->getMessage() ] );
		}
	}

	public function delete_task_comment( $request ) {
		$user_id    = get_current_user_id();
		$comment_id = $request['comment_id'] ?? 0;

		if ( ! $comment_id ) {
			wp_send_json_error( [ 'message' => __( 'Comment ID is required.', 'gemboards' ) ], 400 );
		}

		$existing = get_comment( $comment_id );
		if ( ! $existing ) {
			wp_send_json_error( [ 'message' => __( 'Invalid Comment ID.', 'gemboards' ) ], 404 );
		}
		$task_id = absint( $existing->comment_post_ID );
		if ( ! current_user_can( 'allow_comments', [ 'task_id' => $task_id ] ) ) {
			wp_send_json_error( [ 'message' => __( "You don't have permission to delete comments.", 'gemboards' ) ], 403 );
		}
		if ( absint( $existing->user_id ) !== $user_id ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized to delete this comment.', 'gemboards' ) ], 403 );
		}

		$deleted = wp_delete_comment( $comment_id, true );
		if ( $deleted ) {
			wp_send_json_success( [ 'message' => __( 'Comment deleted successfully.', 'gemboards' ) ] );
		}

		wp_send_json_error( [ 'message' => __( 'Failed to delete comment.', 'gemboards' ) ], 500 );
	}

	public function update_task_title( $request ) {
		$task_id = $request['task_id'];
		$title   = $request['title'];

		if ( ! $task_id || empty( $title ) ) {
			wp_send_json_error( [ 'message' => __( 'Task ID and title are required.', 'gemboards' ) ], 400 );
		}

		try {
			$updated = wp_update_post( [
				'ID'         => $task_id,
				'post_title' => $title,
			] );

			if ( $updated ) {
				wp_send_json_success( [ 'message' => __( 'Task title updated successfully.', 'gemboards' ) ] );
			}
			wp_send_json_error( [ 'message' => __( 'Failed to update task title.', 'gemboards' ) ], 500 );
		} catch ( \Exception $e ) {
			wp_send_json_error( [ 'message' => 'Failed to update task title: ' . $e->getMessage() ] );
		}
	}
}
