<?php

namespace FSPoster\App\Pages\Composer;

use Exception;
use FSPoster\App\Models\Channel;
use FSPoster\App\Models\Schedule;
use FSPoster\App\Providers\Core\Request;
use FSPoster\App\Providers\Core\RestRequest;
use FSPoster\App\Providers\Core\Settings;
use FSPoster\App\Providers\Helpers\Date;
use FSPoster\App\Providers\Schedules\ScheduleService;

class Controller
{
    /**
     * This method is responsible for two actions:
     * 1. Schedule single WordPress post - this is true when $scheduleGroupId is empty, but $wpPostId is set. Because if we schedule WordPress post, we know exact WordPress id.
     * 2. Schedule calendar post - this is true when both $scheduleGroupId and $wpPostId are empty. Because if we create new post from calendar, we don't have WordPress id or schedule group id yet.
     *
     * This method also handles update process. This happens when both $scheduleGroupId and $wpPostId are set. Because we know the schedule group id and WordPress id.
     * As it is hard to match $schedules with schedules in database, we delete all schedules with given group id and create them again. But make sure to delete schedules with status of not_sent.
     *
     * @throws Exception
     */
    public static function save ( RestRequest $request ): array
    {
        $schedulesGroupId = $request->param( 'schedule_group_id', null, Request::TYPE_STRING );
        $wpPostId         = $request->param( 'wp_post_id', null, Request::TYPE_INTEGER );
        $schedules        = $request->param( 'schedules', [], RestRequest::TYPE_ARRAY );
        $shareAt          = $request->param( 'share_at', Date::epoch(), RestRequest::TYPE_INTEGER );

        $isEdit = !empty( $schedulesGroupId ) && !empty( $wpPostId );

        if ( $isEdit )
        {
            $schedulesQuery = Schedule::select('status')
                ->where( 'group_id', $schedulesGroupId )
                ->where( 'wp_post_id', $wpPostId );

            $existingSchedules = $schedulesQuery->fetchAll();

            if ( count( $existingSchedules ) === 0 )
            {
                throw new Exception( fsp__( 'No schedules found' ) );
            }

            array_map( function ( $existingSchedule )
            {
                if ( !in_array( $existingSchedule->status, [ 'draft', 'not_sent' ] ) )
                {
                    throw new Exception( fsp__( 'Something went wrong!' ) );
                }
            }, $existingSchedules );
        }

        if ( empty( $schedules ) )
        {
            throw new Exception( fsp__( 'Schedules can\'t be empty' ) );
        }

        $channelIds = array_column( $schedules, 'channel_id' );

        if ( empty( $channelIds ) )
        {
            throw new Exception( fsp__( 'Please select channels' ) );
        }

        $channelsCount = Channel::where( 'id', $channelIds )->count();

        if ( count( $channelIds ) !== $channelsCount )
        {
            throw new Exception( fsp__( 'You don\'t have access to all the selected channels. Please refresh the page.' ) );
        }

        /**
         * If this is post created from calendar which does not have wp post id, then we should create new post
         */
        if ( empty( $wpPostId ) )
        {
            $wpPostId = wp_insert_post( [
                'post_type'      => 'fsp_post',
                'post_title'     => '[Hidden post generated by FS Poster]',
                'content'        => '',
                'post_date_gmt'  => Date::dateTimeSQL(),
                'post_status'    => 'publish',
                'comment_status' => 'closed',
                'ping_status'    => 'closed',
            ] );
        }

        if ( !empty( $wpPostId ) )
        {
            $post = get_post( $wpPostId );

            if ( !$post )
            {
                throw new Exception( fsp__( 'Post not found' ) );
            }
        } else // in this point $wpPostId should be set, if it is not, then there is a problem
        {
            throw new Exception( fsp__( 'Post not found' ) );
        }

        /**
         * if it is update (group id > 0), then we delete all schedules with given group id
         * then create them again with updated data
         */
        if ( $isEdit )
        {
			Schedule::where( 'group_id', $schedulesGroupId )->delete();
        }

        $newGroupId = ScheduleService::createSchedulesFromWpPost( $wpPostId, $schedulesGroupId, $schedules, $shareAt );

        return [
            'schedule_group_id' => $newGroupId,
        ];
    }

    public static function reschedule ( RestRequest $request ): array
    {
        $schedulesGroupId = $request->param( 'schedule_group_id', null, Request::TYPE_STRING );
        $shareAt          = $request->param( 'share_at', Date::epoch(), RestRequest::TYPE_INTEGER );

        $sendTime = Date::dateTimeSQL( $shareAt );

        $intervalEachPost = Settings::get( 'post_interval', 0 );
        $enablePostInterval = (int)Settings::get('enable_post_interval', 0);

        foreach (Schedule::where( 'group_id', $schedulesGroupId )->fetchAll() as $schedule) {
            Schedule::where('id', $schedule->id)->update( [ 'send_time' => $sendTime ] );

            if ( $intervalEachPost > 0  && $enablePostInterval !== 0) {
                $sendTime = Date::dateTimeSQL($sendTime, '+' . $intervalEachPost . ' seconds');
            }
        }

        return [];
    }

}