<?php

namespace App\Http\Controllers;

use App\Jobs\SyncSubscription;
use App\Models\Subscription;
use App\Models\Calendar;
use App\Models\CalendarInstance;
use App\Models\CalendarMeta;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;

class SubscriptionController extends Controller
{
    public function index()
    {
        $subs = Subscription::where('principaluri', auth()->user()->uri)->get();

        return view('subscription.index', compact('subs'));
    }

    public function create()
    {
        return view('subscription.create');
    }

    public function store(Request $request)
    {
        /* validate the submission */
        $data = $request->validate([
            'source'        => 'required|url',
            'displayname'   => 'nullable|string|max:255',
            'color'         => 'nullable|regex:/^#[0-9A-Fa-f]{6}$/',
            'refreshrate'   => 'nullable|string|max:10',
        ]);

        /* normalize hard to check against this url */
        $source = rtrim(trim($data['source']), '/');

        /* set the principal URI */
        $principalUri = $request->user()->uri;

        /* check for existing subscriptions */
        $already = Subscription::query()
            ->where('principaluri', $principalUri)
            ->where('source', $source)
            ->exists();

        if ($already) {
            return Redirect::route('calendar.index')->with('toast', [
                'message' => __('You are already subscribed to that calendar.'),
                'type'    => 'info',
            ]);
        }

        $sub = DB::transaction(function () use ($data, $principalUri, $source) {

            /* create the calendarsubscriptions record */
            $sub = Subscription::create([
                'uri'           => (string) Str::uuid(),
                'principaluri'  => $principalUri,
                'source'        => $source,
                'displayname'   => $data['displayname'] ?: $source,
                'calendarcolor' => calendar_color($data),
                'refreshrate'   => 'P1D',
                'lastmodified'  => now()->timestamp,
            ]);

            // create new empty calendar container
            $calId = Calendar::create([
                'synctoken'  => 1,
                'components' => 'VEVENT',
            ])->id;

            // create mirror calendarinstance row (description can be user-editable, not relied on)
            CalendarInstance::create([
                'calendarid'    => $calId,
                'principaluri'  => $principalUri,
                'uri'           => (string) Str::uuid(),
                'displayname'   => $sub->displayname,
                'description'   => 'Remote feed: '.$source, // informational only
                'calendarcolor' => $sub->calendarcolor,
                'timezone'      => config('app.timezone', 'UTC'),
            ]);

            // meta entry
            CalendarMeta::updateOrCreate(
                ['calendar_id' => $calId],
                [
                    'subscription_id' => $sub->id,
                    'title'           => $sub->displayname,
                    'color'           => $sub->calendarcolor,
                    'color_fg'        => contrast_text_color($sub->calendarcolor),
                    'is_shared'       => true,
                    'is_remote'       => true,
                ]
            );

            return $sub;
        });

        // sync immediately so events appear without waiting for the */10 dispatcher
        SyncSubscription::dispatch($sub)->afterCommit();

        return Redirect::route('calendar.index')->with('toast', [
            'message' => __('Subscription added! Syncing events now...'),
            'type'    => 'success',
        ]);
    }

    public function edit(Subscription $subscription)
    {
        $this->authorize('update', $subscription);
        return view('subscription.edit', ['subscription' => $subscription]);
    }

    public function update(Request $request, Subscription $subscription)
    {
        $this->authorize('update', $subscription);

        $data = $request->validate([
            'displayname'      => 'nullable|string|max:255',
            'calendarcolor'    => 'nullable|regex:/^#[0-9A-Fa-f]{6}$/',
            'refreshrate'      => 'nullable|string|max:10',
            'striptodos'       => 'sometimes|boolean',
            'stripalarms'      => 'sometimes|boolean',
            'stripattachments' => 'sometimes|boolean',
        ]);

        // update calendarsubscriptions record
        $subscription->update($data);

        // update corresponding calendar_meta record
        $color = calendar_color(['color' => $subscription->calendarcolor]);
        $subscription->meta()->updateOrCreate(
            [], // no “where” clause → look at subscription_id FK
            [
                'title'     => $subscription->displayname,
                'color'     => $color,
                'color_fg'  => contrast_text_color($color),
                'updated_at'=> now(),
            ]
        );

        return back()->with('toast', __('Subscription updated!'));
    }

    public function destroy(Subscription $subscription)
    {
        $this->authorize('delete', $subscription);
        $subscription->delete();

        return back()->with('toast', __('Subscription removed!'));
    }
}
