/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Component, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { MatInputModule } from '@angular/material/input';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatButtonModule } from '@angular/material/button';
import { AsyncPipe } from '@angular/common';
import { NifiSpinnerDirective } from '../../../../../ui/common/spinner/nifi-spinner.directive';
import { selectSaving } from '../../../state/manage-remote-ports/manage-remote-ports.selectors';
import { EditRemotePortDialogRequest } from '../../../state/flow';
import { Client } from '../../../../../service/client.service';
import { PortSummary } from '../../../state/manage-remote-ports';
import { configureRemotePort } from '../../../state/manage-remote-ports/manage-remote-ports.actions';
import { ClusterConnectionService } from '../../../../../service/cluster-connection.service';
import { NifiTooltipDirective, TextTip } from '@nifi/shared';
import { ComponentType, CloseOnEscapeDialog } from '@nifi/shared';
import { CanvasState } from '../../../state';
import { ErrorContextKey } from '../../../../../state/error';
import { ContextErrorBanner } from '../../../../../ui/common/context-error-banner/context-error-banner.component';

@Component({
    templateUrl: './edit-remote-port.component.html',
    imports: [
        ReactiveFormsModule,
        MatDialogModule,
        MatInputModule,
        MatCheckboxModule,
        MatButtonModule,
        AsyncPipe,
        NifiSpinnerDirective,
        NifiTooltipDirective,
        ContextErrorBanner
    ],
    styleUrls: ['./edit-remote-port.component.scss']
})
export class EditRemotePortComponent extends CloseOnEscapeDialog {
    request = inject<EditRemotePortDialogRequest>(MAT_DIALOG_DATA);
    private formBuilder = inject(FormBuilder);
    private store = inject<Store<CanvasState>>(Store);
    private client = inject(Client);
    private clusterConnectionService = inject(ClusterConnectionService);

    saving$ = this.store.select(selectSaving);

    editPortForm: FormGroup;
    portTypeLabel: string;

    constructor() {
        super();
        const request = this.request;

        // set the port type name
        if (ComponentType.InputPort == this.request.type) {
            this.portTypeLabel = 'Input Port';
        } else {
            this.portTypeLabel = 'Output Port';
        }

        // build the form
        this.editPortForm = this.formBuilder.group({
            concurrentTasks: new FormControl(request.entity.concurrentlySchedulableTaskCount, Validators.required),
            compressed: new FormControl(request.entity.useCompression),
            count: new FormControl(request.entity.batchSettings.count),
            size: new FormControl(request.entity.batchSettings.size),
            duration: new FormControl(request.entity.batchSettings.duration)
        });
    }

    editRemotePort() {
        const payload: any = {
            revision: this.client.getRevision(this.request.rpg),
            disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(),
            type: this.request.type,
            remoteProcessGroupPort: {
                concurrentlySchedulableTaskCount: this.editPortForm.get('concurrentTasks')?.value,
                useCompression: this.editPortForm.get('compressed')?.value,
                batchSettings: {
                    count: this.editPortForm.get('count')?.value,
                    size: this.editPortForm.get('size')?.value,
                    duration: this.editPortForm.get('duration')?.value
                },
                id: this.request.entity.id,
                groupId: this.request.entity.groupId
            } as PortSummary
        };

        this.store.dispatch(
            configureRemotePort({
                request: {
                    id: this.request.entity.id,
                    payload
                }
            })
        );
    }

    protected readonly TextTip = TextTip;

    override isDirty(): boolean {
        return this.editPortForm.dirty;
    }

    protected readonly ErrorContextKey = ErrorContextKey;
}
