import { Field, InterfaceType, ObjectType } from '@nestjs/graphql';

import { Node } from '@unraid/shared/graphql.model.js';
import { IsObject, ValidateNested } from 'class-validator';
import { GraphQLJSON } from 'graphql-scalars';

import { SsoSettings } from '@app/unraid-api/graph/resolvers/settings/sso-settings.model.js';

@InterfaceType()
export abstract class FormSchema {
    @Field(() => GraphQLJSON, { description: 'The data schema for the form' })
    @IsObject()
    dataSchema!: Record<string, any>;

    @Field(() => GraphQLJSON, { description: 'The UI schema for the form' })
    @IsObject()
    uiSchema!: Record<string, any>;

    @Field(() => GraphQLJSON, { description: 'The current values of the form' })
    @IsObject()
    values!: Record<string, any>;
}

@ObjectType({
    implements: () => [Node, FormSchema],
})
export class UnifiedSettings extends Node implements FormSchema {
    @Field(() => GraphQLJSON, { description: 'The data schema for the settings' })
    @IsObject()
    dataSchema!: Record<string, any>;

    @Field(() => GraphQLJSON, { description: 'The UI schema for the settings' })
    @IsObject()
    uiSchema!: Record<string, any>;

    @Field(() => GraphQLJSON, { description: 'The current values of the settings' })
    @IsObject()
    values!: Record<string, any>;
}

@ObjectType({
    implements: () => [Node, FormSchema],
})
export class ApiKeyFormSettings extends Node implements FormSchema {
    @Field(() => GraphQLJSON, { description: 'The data schema for the API key form' })
    @IsObject()
    dataSchema!: Record<string, any>;

    @Field(() => GraphQLJSON, { description: 'The UI schema for the API key form' })
    @IsObject()
    uiSchema!: Record<string, any>;

    @Field(() => GraphQLJSON, { description: 'The current values of the API key form' })
    @IsObject()
    values!: Record<string, any>;
}

@ObjectType()
export class UpdateSettingsResponse {
    @Field(() => Boolean, {
        description: 'Whether a restart is required for the changes to take effect',
    })
    restartRequired!: boolean;

    @Field(() => GraphQLJSON, { description: 'The updated settings values' })
    values!: Record<string, any>;

    @Field(() => [String], {
        nullable: true,
        description: 'Warning messages about configuration issues found during validation',
    })
    warnings?: string[];
}

@ObjectType({
    implements: () => Node,
})
export class Settings extends Node {
    @Field(() => UnifiedSettings, { description: 'A view of all settings' })
    @ValidateNested()
    unified!: UnifiedSettings;

    @Field(() => SsoSettings, { description: 'SSO settings' })
    @ValidateNested()
    sso!: SsoSettings;
}
