'use client'
import React, {
    ChangeEvent,
    ChangeEventHandler,
    LegacyRef,
    MouseEventHandler,
    MutableRefObject,
    ReactNode,
    useLayoutEffect,
    useRef
} from "react";
import TableGen from "../TableGen";
import toast from "react-hot-toast";
import PostEditor, { EditorProps } from "./PostEditor";
import {
    Attributes,
    CreationAttributes
} from "@sequelize/core";
import { useState } from "react";
import { Project, Post, Bucket } from "@/model/Models";
import { ActionResult } from "@/app/lib/actions/ActionResult";
import { handleActionResult } from "@/app/lib/actions/clientActionHandler";
import { getPostsWithBuckets } from "@/app/lib/actions/entityManagement/postActions";
import { PostAttributesWithBuckets } from "@/model/Post";

type Actions = {
    deletePost: (id: number) => Promise<ActionResult<boolean>>
    getPosts: () => Promise<ActionResult<PostAttributesWithBuckets[]>>
    getProjects: () => Promise<ActionResult<Attributes<Project>[]>>
    savePost: (data: Partial<Attributes<Post>>) => Promise<ActionResult<Attributes<Post>[]>>
    // uploadAttachment: ()=> Promise<ActionResult<any>>
};

type Props = {
    children?: ReactNode;
    headings: Array<string>;
    data: Partial<PostAttributesWithBuckets>[];
    projects: Attributes<Project>[];
    actions: Actions;
}

const aifa = (a: ReactNode, b: ReactNode) => a ? a : b

export default function PostTable(props: Props) {



    const initEditorState: Partial<EditorProps> = {
        editorOpenState: false
    }

    // Set up required state hooks
    const [posts, setPosts] = useState(props.data);
    const [editor, setEditor] = useState(initEditorState)
    const [projects, setProjects] = useState(props.projects);

    // Define editor controls

    function closeEditor(): void {
        setEditor({
            editorOpenState: false
        })
    }
    function showEditor(entry: Partial<PostAttributesWithBuckets>): void {
        setEditor({
            editorOpenState: true,
            openedPost: entry
        })
    }

    function deletePost(entry: Partial<PostAttributesWithBuckets>) {
        if (!entry.id) return;
        props.actions?.deletePost(entry.id)
            .then(actionResult => {
                const result = handleActionResult(actionResult);
                if (!result) return;
                posts.splice(posts.indexOf(entry), 1);
                setPosts([...posts])
                toast.success('Removed Post:' + entry.id);
            });
    }

    function refetch() {
        props.actions.getPosts()
            .then((p) => {
                const result = handleActionResult(p)
                if (result) setPosts(result)
            }).then(props.actions.getProjects)
            .then(e => {
                const result = handleActionResult(e);
                if (result) setProjects(result)
            })
    }

    function savePost(e: Partial<PostAttributesWithBuckets>) {
        props.actions.savePost({
            id: e.id,
            content: e.content,
            title: e.title,
            project_id: e.project_id
        })
            .then(res => handleActionResult(res))
            .then(getPostsWithBuckets)
            .then(res => {
                if (!res.error && res.result) setPosts(res.result);
            })
        closeEditor();
    };

    function TableFields({ postData }: { postData: Partial<PostAttributesWithBuckets> }) {
        return [
            {
                key: 'post-title',
                content: postData.title
            }, {
                key: 'post-content',
                content:
                    !postData.content ? "No Content Found" :
                        postData.content.length < 255 ? postData.content :
                            `${postData.content.substring(0, 255)}...`

            }, {
                key: 'post-project',
                content: aifa((projects.find((e) => {
                    return (e.id == postData.project_id)
                })?.readableIdentifier), 'uncategorized')
            }, {
                key: 'post-createdat',
                content: postData.createdAt?.toString()
            }, {
                key: 'post-updatedat',
                content: postData.updatedAt?.toString()
            }, {
                key: 'post-editbutton',
                content: <button key="editbutton" type="button" className="btn btn-primary" onClick={() => showEditor(postData)}>Edit</button>
            }, {
                key: 'post-deletebutton',
                content: <button key="deletebutton" type="button" className="btn btn-danger" onClick={() => deletePost(postData)}> Delete</button>
            }
        ].map(field => 
            <td key={field.key}>{field.content}</td>
        );
    }

    function TableRow(props: {postData: Partial<PostAttributesWithBuckets>, headings: string | any[]}){
                return <><tr key={props.postData.id}>
                    <th key={`rowheading-post-${props.postData.id}`} scope="row">{props.postData.id}</th>
                    <TableFields key={`tableFields-${props.postData.id}`} postData={props.postData} />
                </tr>
                {(editor.editorOpenState
                    && editor.openedPost
                    && editor.openedPost.id == props.postData.id)

                    ? <tr>
                        <th scope="row" colSpan={props.headings.length}>
                            <PostEditor callbacks={{
                                savePost: savePost,
                                closeEditor: closeEditor,
                                uploadAttachment: () => { }
                            }}
                                editorOpenState={editor.editorOpenState}
                                openedPost={editor.openedPost}
                                projects={projects} />
                        </th>
                    </tr>

                    : ""}
                </>
    }

    return <>
        <TableGen key="der-table" headings={props.headings}>
            {posts.map((postData: Partial<PostAttributesWithBuckets>) => <TableRow  headings={props.headings} 
                                                                                    postData={postData} 
                                                                                    key={postData.id}/> )}
        </TableGen>
    </>
}