import {CardRenderer} from "../CardRenderers";
import {ComponentMeta} from "../ComponentsMeta";
import {IncompatibleWithAnyProducts} from "../IncompatibleWithAnyProducts";
import {__, CouponsPlus} from "../../globals";
import {iconWithClassName} from "../IconWithClassName";
import {FieldType} from "../fields";
import {inclusionValueValidatorFieldsMap, InclusionValueValidatorOptions} from "./InclusionValueValidator";
import {AttributeFields, CustomVariation} from "./AttributeFields";
import {usingTestableOptions} from "./CardHelpers";
import {getAttributeName, getAttributeValueNames} from "./attributeHelpers";

export type AttributesOptions = InclusionValueValidatorOptions<CustomVariation>

export const type = CouponsPlus?.components?.filters?.Attributes?.type ?? 'Attributes';
export const AttributesMeta: ComponentMeta = IncompatibleWithAnyProducts({
    id: type,
    type: 'filters',
    //fieldsTitlePrefix: false,
    category: 'common',
    priority: 40,
    supportsCustomTitleForSuggestedScopes: (suggestedScope) => true,
    icon: iconWithClassName(({className, context}) => {
        if (context === 'card') {
            // solid
            return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="size-6">
                <path
                    d="M11.25 5.337c0-.355-.186-.676-.401-.959a1.647 1.647 0 0 1-.349-1.003c0-1.036 1.007-1.875 2.25-1.875S15 2.34 15 3.375c0 .369-.128.713-.349 1.003-.215.283-.401.604-.401.959 0 .332.278.598.61.578 1.91-.114 3.79-.342 5.632-.676a.75.75 0 0 1 .878.645 49.17 49.17 0 0 1 .376 5.452.657.657 0 0 1-.66.664c-.354 0-.675-.186-.958-.401a1.647 1.647 0 0 0-1.003-.349c-1.035 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401.31 0 .557.262.534.571a48.774 48.774 0 0 1-.595 4.845.75.75 0 0 1-.61.61c-1.82.317-3.673.533-5.555.642a.58.58 0 0 1-.611-.581c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.035-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959a.641.641 0 0 1-.658.643 49.118 49.118 0 0 1-4.708-.36.75.75 0 0 1-.645-.878c.293-1.614.504-3.257.629-4.924A.53.53 0 0 0 5.337 15c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.036 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.369 0 .713.128 1.003.349.283.215.604.401.959.401a.656.656 0 0 0 .659-.663 47.703 47.703 0 0 0-.31-4.82.75.75 0 0 1 .83-.832c1.343.155 2.703.254 4.077.294a.64.64 0 0 0 .657-.642Z"/>
            </svg>


        }
        // outline
        return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5}
                    stroke="currentColor" className="size-6">
            <path strokeLinecap="round" strokeLinejoin="round"
                  d="M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 0 1-.657.643 48.39 48.39 0 0 1-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 0 1-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 0 0-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 0 1-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 0 0 .657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 0 1-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.4.604-.4.959v0c0 .333.277.599.61.58a48.1 48.1 0 0 0 5.427-.63 48.05 48.05 0 0 0 .582-4.717.532.532 0 0 0-.533-.57v0c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.37 0 .713.128 1.003.349.283.215.604.401.96.401v0a.656.656 0 0 0 .658-.663 48.422 48.422 0 0 0-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 0 1-.61-.58v0Z"/>
        </svg>

    }),
    fieldsMap: [
        [
            {id: 'inclusionType', renderType: FieldType.Tab, fieldProps: {size: 'normal'}},
        ],
        [
            {
                id: 'expectedValues',
                renderType: FieldType.Custom,
                fieldProps: (options: AttributesOptions, onUpdate, {componentRuntimeData, field}) => {
                    return {
                        component: <AttributeFields inclusionType={options.inclusionType as 'allowed' | 'forbidden'}
                                                    variations={options.expectedValues}
                                                    onNewVariation={newVariation => {
                                                        // here we need to add the new variation to the testable
                                                        onUpdate(
                                                            componentRuntimeData,
                                                            field,
                                                            newVariation,
                                                            // @ts-ignore
                                                            {action: 'add'} // cannot import the enum because of a circular dependency
                                                        )
                                                    }}
                                                    onRemoveVariation={(variationIndex) => onUpdate(
                                                        componentRuntimeData,
                                                        field,
                                                        null, // we don't need to pass the variation here, just the index
                                                        {
                                                            // @ts-ignore
                                                            action: 'remove', // cannot import the enum because of a circular dependency
                                                        },
                                                        `[${variationIndex}]`
                                                    )}
                                                    onVariationChange={(variationIndex, attributeIndex, attribute) => {
                                                        // here we'll send to update only
                                                        // set the path using index (eg: extraNestedFieldPathRelative = `expectedValues[${variationIndex}]attribute[${attributeIndex}]`)
                                                        // so that only one attribute is updated
                                                        // and not th whole thing
                                                        onUpdate(
                                                            componentRuntimeData,
                                                            field,
                                                            attribute,
                                                            {
                                                                // @ts-ignore
                                                                action: attribute ? 'update' : 'remove', // cannot import the enum because of a circular dependency
                                                            },
                                                            `[${variationIndex}][${attributeIndex}]`
                                                        )

                                                    }}
                                                    onNewAttribute={(variationIndex, attribute) => {
                                                        onUpdate(
                                                            componentRuntimeData,
                                                            field,
                                                            attribute,
                                                            {
                                                                // @ts-ignore
                                                                action: 'add', // cannot import the enum because of a circular dependency
                                                            }
                                                            ,
                                                            `[${variationIndex}]`
                                                        )
                                                    }}
                        />
                    }
                }
            }
        ]
    ]
})

export const AttributesRenderer: CardRenderer<AttributesOptions> = {
    type: AttributesMeta.id,
    icon: AttributesMeta.icon!,
    prefix: __('[Items with] [Specific] *'),
    example: __('Color, Size, Weight, etc.'),
    ComputedValue: usingTestableOptions<AttributesOptions>(({expectedValues}) => <div
        className="space-y-1">
        {expectedValues.map(attributes => <>
            <div className="space-y-1 ---pt-2 first:pt-[2px]">
                {attributes.map(({type, attribute}) => {
                    const attributevalues = getAttributeValueNames(attribute)
                    return <div className="flex flex-col">
                        <span className="text-smaller-1 opacity-60 leading-3">{
                            type === 'excluded' ? __('Any * except').replace('*', getAttributeName(attribute)) : getAttributeName(attribute)
                        }</span>
                        <div>{type === 'any' ? __('Any') : (attributevalues.length ? attributevalues.map(name => <div
                            className="flex items-center space-x-1">
                            {type === 'excluded' &&
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
                                     className="min-w-3 min-h-3 max-w-3 max-h-3">
                                    <path fillRule="evenodd"
                                          d="m5.965 4.904 9.131 9.131a6.5 6.5 0 0 0-9.131-9.131Zm8.07 10.192L4.904 5.965a6.5 6.5 0 0 0 9.131 9.131ZM4.343 4.343a8 8 0 1 1 11.314 11.314A8 8 0 0 1 4.343 4.343Z"
                                          clipRule="evenodd"/>
                                </svg>
                            }<span>{name}</span>
                        </div>) : <div className="opacity-60">{__('Select values')}</div>)}
                        </div>
                    </div>

                })}
            </div>
            <div className="flex items-center gap-2 last:hidden">
                <div className="flex-1 border-t border-dashed border-gray-300"></div>
                <span className="text-smaller-3 opacity-80 leading-4">OR</span>
                <div className="flex-1 border-t border-dashed border-gray-300"></div>
            </div>
        </>)}
        {!(!!expectedValues.length) && <div className="opacity-60">{__('Add custom variations')}</div>}
    </div>),
    AboveComputedValue: usingTestableOptions<AttributesOptions>(({inclusionType}) => inclusionType === 'forbidden' ? __('Excluding') : false),
}