import * as icon from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import React, { ReactElement, useEffect, useMemo, useState } from 'react';
import BaseButton from '../components/BaseButton';
import BaseIcon from '../components/BaseIcon';
import CardBox from '../components/CardBox';
import FormField from '../components/FormField';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import LayoutAuthenticated from '../layouts/Authenticated';
import { getPageTitle } from '../config';
import { useAppSelector } from '../stores/hooks';

type SocialComment = {
  id: string;
  post_id: string;
  user: string;
  comment: string;
  parent_id: string;
  created_at: string;
};

type SocialPost = {
  id: string;
  user: string;
  content: string;
  created_at: string;
  comments: SocialComment[];
};

type SocialFeed = {
  posts: SocialPost[];
  stats: {
    postsCount: number;
    commentsCount: number;
  };
  syncedAt: string;
};

type SocialMutationResponse = {
  feed: SocialFeed;
};

type NoticeTone = 'info' | 'success' | 'warning' | 'danger';

const resolveIcon = (name: string) => (
  name in icon ? (icon[name as keyof typeof icon] as string) : icon.mdiViewDashboardOutline
);

const formatDateTime = (value?: string) => {
  if (!value) {
    return '-';
  }

  try {
    return new Intl.DateTimeFormat('id-ID', {
      dateStyle: 'medium',
      timeStyle: 'short',
    }).format(new Date(value));
  } catch (error) {
    console.error('Failed to format VORTA feed date:', error);
    return value;
  }
};

const VortaFeedPage = () => {
  const { currentUser } = useAppSelector((state) => state.auth);
  const [feed, setFeed] = useState<SocialFeed | null>(null);
  const [postContent, setPostContent] = useState('');
  const [commentDrafts, setCommentDrafts] = useState<Record<string, string>>({});
  const [replyDrafts, setReplyDrafts] = useState<Record<string, string>>({});
  const [activeReplyId, setActiveReplyId] = useState<string | null>(null);
  const [notice, setNotice] = useState('');
  const [noticeTone, setNoticeTone] = useState<NoticeTone>('info');
  const [errorMessage, setErrorMessage] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);

  const displayName = useMemo(() => {
    const name = [currentUser?.firstName, currentUser?.lastName].filter(Boolean).join(' ').trim();
    return name || currentUser?.email || 'VORTA Member';
  }, [currentUser]);

  const loadFeed = async () => {
    setIsLoading(true);
    setErrorMessage('');

    try {
      const response = await axios.get<SocialFeed>('/vorta-universe/social-feed');
      setFeed(response.data);
      setNotice(`Feed tersinkron dari PostgreSQL: ${formatDateTime(response.data.syncedAt)}`);
      setNoticeTone('success');
    } catch (error) {
      console.error('Failed to load VORTA Feed:', error);
      setErrorMessage('Gagal memuat VORTA Feed. Cek koneksi dan backend log untuk detail.');
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    loadFeed();
  }, []);

  const runMutation = async (
    action: () => Promise<{ data: SocialMutationResponse }>,
    successMessage: string,
  ) => {
    setIsSaving(true);
    setErrorMessage('');
    setNotice('');

    try {
      const response = await action();
      setFeed(response.data.feed);
      setNotice(successMessage);
      setNoticeTone('success');
      return true;
    } catch (error) {
      console.error('Failed to mutate VORTA Feed:', error);
      setErrorMessage('Aksi feed gagal disimpan. Cek input dan backend log untuk detail.');
      return false;
    } finally {
      setIsSaving(false);
    }
  };

  const createPost = async () => {
    if (!postContent.trim()) {
      setErrorMessage('Isi post terlebih dahulu sebelum menerbitkan.');
      return;
    }

    const saved = await runMutation(
      () => axios.post<SocialMutationResponse>('/vorta-universe/posts', {
        data: {
          user: displayName,
          content: postContent,
        },
      }),
      'Post baru berhasil tersimpan di tabel vorta_social_posts.',
    );

    if (saved) {
      setPostContent('');
    }
  };

  const createComment = async (postId: string, parentId = '0') => {
    const draftKey = parentId === '0' ? postId : parentId;
    const draft = parentId === '0' ? commentDrafts[postId] : replyDrafts[parentId];

    if (!draft?.trim()) {
      setErrorMessage(parentId === '0' ? 'Isi komentar terlebih dahulu.' : 'Isi balasan terlebih dahulu.');
      return;
    }

    const saved = await runMutation(
      () => axios.post<SocialMutationResponse>(`/vorta-universe/posts/${postId}/comments`, {
        data: {
          user: displayName,
          comment: draft,
          parent_id: parentId,
        },
      }),
      parentId === '0'
        ? 'Komentar baru berhasil tersimpan di tabel vorta_social_comments.'
        : 'Balasan komentar berhasil tersimpan dengan parent_id.',
    );

    if (saved && parentId === '0') {
      setCommentDrafts((drafts) => ({ ...drafts, [draftKey]: '' }));
    }

    if (saved && parentId !== '0') {
      setReplyDrafts((drafts) => ({ ...drafts, [draftKey]: '' }));
      setActiveReplyId(null);
    }
  };

  const resetFeed = async () => {
    const saved = await runMutation(
      () => axios.post<SocialMutationResponse>('/vorta-universe/social-feed/reset'),
      'Feed berhasil di-reset ke contoh awal VORTA.',
    );

    if (saved) {
      setPostContent('');
      setCommentDrafts({});
      setReplyDrafts({});
      setActiveReplyId(null);
    }
  };

  const clearDrafts = () => {
    setPostContent('');
    setCommentDrafts({});
    setReplyDrafts({});
    setActiveReplyId(null);
    setNotice('Semua draft di layar sudah dibersihkan. Data tersimpan tidak dihapus.');
    setNoticeTone('info');
    setErrorMessage('');
  };

  const posts = feed?.posts || [];
  const commentsCount = feed?.stats.commentsCount || 0;

  return (
    <>
      <Head>
        <title>{getPageTitle('VORTA Feed')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={resolveIcon('mdiPostOutline')}
          title="VORTA Feed"
          main
        >
          <BaseButton
            label={isLoading ? 'Memuat...' : 'Refresh'}
            icon={resolveIcon('mdiRefresh')}
            color="info"
            onClick={loadFeed}
            disabled={isLoading || isSaving}
          />
        </SectionTitleLineWithButton>

        <div className="mb-6 grid grid-cols-1 gap-4 lg:grid-cols-3">
          <CardBox className="border border-emerald-500/30 bg-emerald-950/10">
            <div className="flex items-center gap-3">
              <BaseIcon path={resolveIcon('mdiDatabaseCheckOutline')} size={32} className="text-emerald-500" />
              <div>
                <p className="text-sm text-gray-500 dark:text-gray-400">Storage</p>
                <h2 className="text-xl font-bold">PostgreSQL Native</h2>
              </div>
            </div>
          </CardBox>
          <CardBox>
            <div className="flex items-center gap-3">
              <BaseIcon path={resolveIcon('mdiPostOutline')} size={32} className="text-sky-500" />
              <div>
                <p className="text-sm text-gray-500 dark:text-gray-400">Posts</p>
                <h2 className="text-xl font-bold">{posts.length}</h2>
              </div>
            </div>
          </CardBox>
          <CardBox>
            <div className="flex items-center gap-3">
              <BaseIcon path={resolveIcon('mdiCommentMultipleOutline')} size={32} className="text-amber-500" />
              <div>
                <p className="text-sm text-gray-500 dark:text-gray-400">Comments & Replies</p>
                <h2 className="text-xl font-bold">{commentsCount}</h2>
              </div>
            </div>
          </CardBox>
        </div>

        {(notice || errorMessage) && (
          <div
            className={`mb-6 rounded-xl border px-4 py-3 text-sm ${
              errorMessage
                ? 'border-red-500/40 bg-red-500/10 text-red-700 dark:text-red-200'
                : noticeTone === 'success'
                  ? 'border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-200'
                  : noticeTone === 'warning'
                    ? 'border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-200'
                    : 'border-sky-500/40 bg-sky-500/10 text-sky-700 dark:text-sky-200'
            }`}
          >
            {errorMessage || notice}
          </div>
        )}

        <div className="grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,420px)_1fr]">
          <div className="space-y-6">
            <CardBox>
              <div className="mb-4">
                <p className="text-sm font-semibold uppercase tracking-wide text-emerald-600 dark:text-emerald-300">
                  Create Post
                </p>
                <h2 className="text-2xl font-bold">Tulis update komunitas</h2>
                <p className="mt-2 text-sm text-gray-600 dark:text-gray-400">
                  Post tersimpan sebagai row baru di <strong>vorta_social_posts</strong> dan langsung muncul di feed.
                </p>
              </div>

              <FormField label="Nama tampil" help="Diambil dari akun login, bisa ikut tersimpan sebagai user display feed.">
                <input value={displayName} disabled />
              </FormField>

              <FormField label="Konten Post" hasTextareaHeight>
                <textarea
                  value={postContent}
                  onChange={(event) => setPostContent(event.target.value)}
                  placeholder="Contoh: Update bisnis hari ini, promo komunitas, atau ide kolaborasi VORTA..."
                />
              </FormField>

              <div className="flex flex-wrap gap-2">
                <BaseButton
                  label={isSaving ? 'Menyimpan...' : 'Terbitkan Post'}
                  icon={resolveIcon('mdiSend')}
                  color="success"
                  onClick={createPost}
                  disabled={isSaving || isLoading}
                />
                <BaseButton
                  label="Bersihkan Draft"
                  icon={resolveIcon('mdiBroom')}
                  color="warning"
                  outline
                  onClick={clearDrafts}
                  disabled={isSaving || isLoading}
                />
                <BaseButton
                  label="Reset Demo"
                  icon={resolveIcon('mdiRestore')}
                  color="danger"
                  outline
                  onClick={resetFeed}
                  disabled={isSaving || isLoading}
                />
              </div>
            </CardBox>

            <CardBox>
              <p className="text-sm font-semibold uppercase tracking-wide text-sky-600 dark:text-sky-300">
                API aktif
              </p>
              <div className="mt-3 space-y-3 text-sm text-gray-600 dark:text-gray-300">
                <p><strong>GET</strong> /vorta-universe/social-feed</p>
                <p><strong>POST</strong> /vorta-universe/posts</p>
                <p><strong>POST</strong> /vorta-universe/posts/:postId/comments</p>
                <p><strong>POST</strong> /vorta-universe/social-feed/reset</p>
              </div>
            </CardBox>
          </div>

          <div className="space-y-5">
            {isLoading && !feed && (
              <CardBox>
                <div className="py-10 text-center text-gray-500 dark:text-gray-400">Memuat VORTA Feed...</div>
              </CardBox>
            )}

            {!isLoading && posts.length === 0 && (
              <CardBox>
                <div className="py-10 text-center">
                  <BaseIcon path={resolveIcon('mdiPostOutline')} size={48} className="mx-auto mb-3 text-gray-400" />
                  <h3 className="text-xl font-bold">Belum ada post</h3>
                  <p className="mt-2 text-gray-600 dark:text-gray-400">Buat post pertama untuk memulai feed komunitas.</p>
                </div>
              </CardBox>
            )}

            {posts.map((post) => {
              const rootComments = post.comments.filter((comment) => comment.parent_id === '0');
              const repliesByParent = post.comments.reduce<Record<string, SocialComment[]>>((acc, comment) => {
                if (comment.parent_id !== '0') {
                  acc[comment.parent_id] = acc[comment.parent_id] || [];
                  acc[comment.parent_id].push(comment);
                }

                return acc;
              }, {});

              return (
                <CardBox key={post.id} className="overflow-hidden">
                  <div className="mb-4 flex flex-col gap-3 border-b border-gray-200 pb-4 dark:border-dark-700 md:flex-row md:items-start md:justify-between">
                    <div>
                      <div className="flex items-center gap-3">
                        <div className="flex h-11 w-11 items-center justify-center rounded-full bg-emerald-500/15 text-lg font-bold text-emerald-600 dark:text-emerald-300">
                          {post.user.slice(0, 1).toUpperCase()}
                        </div>
                        <div>
                          <h3 className="font-bold">{post.user}</h3>
                          <p className="text-xs text-gray-500 dark:text-gray-400">{formatDateTime(post.created_at)}</p>
                        </div>
                      </div>
                      <p className="mt-4 whitespace-pre-wrap text-gray-800 dark:text-gray-100">{post.content}</p>
                    </div>
                    <div className="rounded-full bg-sky-500/10 px-3 py-1 text-xs font-semibold text-sky-700 dark:text-sky-200">
                      {post.comments.length} komentar
                    </div>
                  </div>

                  <div className="space-y-4">
                    {rootComments.map((comment) => (
                      <div key={comment.id} className="rounded-xl border border-gray-200 p-3 dark:border-dark-700">
                        <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                          <div className="font-semibold">{comment.user}</div>
                          <div className="text-xs text-gray-500 dark:text-gray-400">{formatDateTime(comment.created_at)}</div>
                        </div>
                        <p className="mt-2 whitespace-pre-wrap text-sm text-gray-700 dark:text-gray-200">{comment.comment}</p>

                        {(repliesByParent[comment.id] || []).map((reply) => (
                          <div key={reply.id} className="mt-3 border-l-4 border-emerald-400 pl-3">
                            <div className="flex flex-col gap-1 text-xs text-gray-500 dark:text-gray-400 sm:flex-row sm:items-center sm:justify-between">
                              <span className="font-semibold text-gray-700 dark:text-gray-200">{reply.user}</span>
                              <span>{formatDateTime(reply.created_at)}</span>
                            </div>
                            <p className="mt-1 whitespace-pre-wrap text-sm text-gray-700 dark:text-gray-200">{reply.comment}</p>
                          </div>
                        ))}

                        {activeReplyId === comment.id ? (
                          <div className="mt-3 flex flex-col gap-2 md:flex-row">
                            <input
                              className="min-h-10 flex-1 rounded border border-gray-300 px-3 py-2 dark:border-dark-700 dark:bg-dark-800"
                              value={replyDrafts[comment.id] || ''}
                              onChange={(event) => setReplyDrafts((drafts) => ({
                                ...drafts,
                                [comment.id]: event.target.value,
                              }))}
                              placeholder="Tulis balasan..."
                            />
                            <BaseButton
                              label="Kirim Reply"
                              color="success"
                              small
                              onClick={() => createComment(post.id, comment.id)}
                              disabled={isSaving}
                            />
                            <BaseButton
                              label="Batal"
                              color="warning"
                              small
                              outline
                              onClick={() => setActiveReplyId(null)}
                              disabled={isSaving}
                            />
                          </div>
                        ) : (
                          <button
                            type="button"
                            className="mt-3 text-sm font-semibold text-emerald-600 hover:underline dark:text-emerald-300"
                            onClick={() => setActiveReplyId(comment.id)}
                          >
                            Balas komentar
                          </button>
                        )}
                      </div>
                    ))}

                    <div className="flex flex-col gap-2 border-t border-gray-200 pt-4 dark:border-dark-700 md:flex-row">
                      <input
                        className="min-h-11 flex-1 rounded border border-gray-300 px-3 py-2 dark:border-dark-700 dark:bg-dark-800"
                        value={commentDrafts[post.id] || ''}
                        onChange={(event) => setCommentDrafts((drafts) => ({
                          ...drafts,
                          [post.id]: event.target.value,
                        }))}
                        placeholder="Tulis komentar untuk post ini..."
                      />
                      <BaseButton
                        label="Komentar"
                        icon={resolveIcon('mdiCommentPlusOutline')}
                        color="info"
                        onClick={() => createComment(post.id)}
                        disabled={isSaving || isLoading}
                      />
                    </div>
                  </div>
                </CardBox>
              );
            })}
          </div>
        </div>
      </SectionMain>
    </>
  );
};

VortaFeedPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};

export default VortaFeedPage;
