import React, { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';
import { Icon } from '@squiz/generic-browser-lib';

import sampleSources from './sample-sources.json';
import { ResourceBrowserPlugin, ResourceBrowserResource } from '../types';
type CreateCallbacksProps = Partial<{
    delay: number;
    sourceIsLoading: boolean;
    singleSource?: boolean;
    error?: string;
}>;

export const createPlugins = (callbackWait: number, headerPortal = false, resourceError?: boolean): ResourceBrowserPlugin[] => {
    const types = ['dam', 'matrix'];
    return types.map((type): ResourceBrowserPlugin => {
        return {
            //@ts-ignore
            type,
            createHeaderPortal: headerPortal,
            sourceBrowserComponent: () => {
                return (props) => {
                    console.log('sourceBrowserComponent invoked with', props);
                    return (
                        <div className="h-screen lg:h-[calc(100vh-9rem)] w-screen max-w-[52rem]">
                            <div>THIS IS A {type} BROWSE PLUGIN</div>
                            <button
                                onClick={() => {
                                    props.onSelected({
                                        id: '1f7a25b4-380f-4540-9555-8be2dcab4019',
                                        source: props.source,
                                    } as ResourceBrowserResource);
                                }}
                            >
                                Press to set resource
                            </button>
                            {headerPortal && props.headerPortal && createPortal(<div>HeadPortal</div>, props.headerPortal)}
                        </div>
                    );
                };
            },
            sourceSearchComponent: () => {
                return (props) => {
                    console.log('sourceSearchComponent invoked with', props);
                    return (
                        <div className="h-screen lg:h-[calc(100vh-9rem)] w-screen max-w-[52rem]">
                            <div>THIS IS A {type} SEARCH PLUGIN</div>
                            <div>Received query: {props.query}</div>
                            <button
                                onClick={() => {
                                    props.onSelected({
                                        id: '1f7a25b4-380f-4540-9555-8be2dcab4019',
                                        source: props.source,
                                    } as ResourceBrowserResource);
                                }}
                            >
                                Press to set resource
                            </button>
                            {headerPortal && props.headerPortal && createPortal(<div>HeadPortal</div>, props.headerPortal)}
                        </div>
                    );
                };
            },
            renderResourceLauncher: () => {
                return (props) => {
                    const [query, setQuery] = useState<string>('');
                    return (
                        <div className="">
                            <div>Search {type}</div>
                            <form>
                                <input onChange={(event) => setQuery(event.target.value)} />
                                <button onClick={() => props.onSearch(query)}>Search</button>
                            </form>
                            <button onClick={props.onBrowse}>Browse</button>
                        </div>
                    );
                };
            },
            renderSelectedResource: (resource) => {
                return new Promise((resolve, reject) => {
                    const fileSize = resource.squizImage?.imageVariations?.original?.byteSize;
                    const fileWidth = resource.squizImage?.imageVariations?.original?.width;
                    const fileHeight = resource.squizImage?.imageVariations?.original?.height;

                    setTimeout(() => {
                        resolve({
                            showThumbnail: resource.squizImage ? true : false,
                            icon: <Icon icon={resource.type.code} resourceSource="matrix" className="" />,
                            label: resource.name || resource.squizImage?.name || resource.id,
                            description: resource.squizImage
                                ? [
                                      <dl
                                          key="1"
                                          className="col-start-2 col-end-2 flex flex-row gap-1 justify-self-start items-center font-normal text-sm"
                                      >
                                          <div>
                                              <span>{type} plugin</span>
                                              <dt className="hidden">Asset size</dt>
                                              <dd className="text-gray-600">
                                                  {resource.squizImage && (
                                                      <>
                                                          {fileSize} kB , {fileWidth} x {fileHeight}px
                                                      </>
                                                  )}
                                              </dd>
                                          </div>
                                      </dl>,
                                  ]
                                : undefined,
                        });
                    }, callbackWait);
                });
            },
            useResolveResource: (unresolvedResource) => {
                const [resource, setResource] = useState<ResourceBrowserResource | null>(null);
                const [error, setError] = useState<Error | null>(
                    resourceError ? new Error(`Error loading: ${JSON.stringify(unresolvedResource)}`) : null,
                );
                const [isLoading, setIsLoading] = useState<boolean>(false);

                if (resourceError) {
                    console.log('useResolveResource has returned an error');
                }
                useEffect(() => {
                    if (unresolvedResource !== null) {
                        const forceType: string = unresolvedResource.forceResourceType;
                        setTimeout(() => {
                            setIsLoading(false);
                            setResource({
                                id: unresolvedResource.resource,
                                name: 'An image from Bynder',
                                url: 'https://cdn.mediavalet.com/aunsw/squiz/KfIjcjUJz0O6kWoInBys5A/XpBxg3Hj-0qOXFWnAAWvXQ/Large/RX-7.jpeg',
                                source: unresolvedResource.source,
                                type: {
                                    code: forceType ? forceType : 'jpeg',
                                    name: 'JPEG image',
                                },
                                squizImage: forceType
                                    ? undefined
                                    : {
                                          name: 'An image from Bynder',
                                          imageVariations: {
                                              original: {
                                                  width: 1024,
                                                  height: 900,
                                                  url: 'https://cdn.mediavalet.com/aunsw/squiz/KfIjcjUJz0O6kWoInBys5A/XpBxg3Hj-0qOXFWnAAWvXQ/Large/RX-7.jpeg',
                                                  mimeType: 'image/jpeg',
                                                  byteSize: 1068,
                                                  sha1Hash: '',
                                                  aspectRatio: '',
                                              },
                                          },
                                      },
                            });
                        }, callbackWait);
                    } else {
                        setResource(null);
                        setIsLoading(false);
                    }
                }, [unresolvedResource, setResource, setIsLoading]);

                return {
                    data: !error ? resource : null,
                    error: error,
                    isLoading: isLoading,
                };
            },
        };
    });
};

export const createResourceBrowserCallbacks = ({
    delay = 500,
    sourceIsLoading = false,
    error,
    singleSource = false,
}: CreateCallbacksProps = {}) => {
    return {
        onRequestSources: () => {
            console.log(`onRequestSources invoked`);
            return new Promise((resolve, reject) => {
                if (!sourceIsLoading) {
                    setTimeout(() => {
                        if (error) {
                            reject(new Error(error));
                        } else {
                            resolve(singleSource ? [sampleSources[0]] : sampleSources);
                        }
                    }, delay);
                }
            });
        },
    };
};
