import {
  mdiBookOpenVariant,
  mdiCalendarClock,
  mdiCheck,
  mdiCheckCircleOutline,
  mdiChevronRight,
  mdiFlagVariantOutline,
  mdiMessageReplyTextOutline,
  mdiPencilOutline,
} from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import React from 'react';
import type { ReactElement } from 'react';
import BaseIcon from '../components/BaseIcon';
import SectionMain from '../components/SectionMain';
import { getPageTitle } from '../config';
import LayoutAuthenticated from '../layouts/Authenticated';
import { useAppSelector } from '../stores/hooks';

type PortalClient = {
  id: string;
  name: string;
  email?: string;
  goals?: string;
  next_session_at?: string;
  sessions?: Array<{ id: string; title: string; shared_client_notes?: string }>;
  action_items?: Array<{ id: string; title: string; status: string }>;
  prep_briefs?: Array<{
    id: string;
    client_reflection?: string;
    client_reflection_at?: string;
  }>;
  resources?: Array<{
    id: string;
    title: string;
    description?: string;
    url?: string;
  }>;
};

function Panel({
  children,
  className = '',
}: {
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <section
      className={`rounded-none border border-[#19192d]/10 bg-white ${className}`}
    >
      {children}
    </section>
  );
}

function formatDate(value?: string) {
  if (!value) {
    return 'Not scheduled';
  }

  return new Intl.DateTimeFormat('en', {
    month: 'short',
    day: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
  }).format(new Date(value));
}

const ClientPortal = () => {
  const { currentUser } = useAppSelector((state) => state.auth);
  const [clients, setClients] = React.useState<PortalClient[]>([]);
  const [clientId, setClientId] = React.useState('');
  const [portalClient, setPortalClient] = React.useState<PortalClient | null>(
    null,
  );
  const [updatingItemId, setUpdatingItemId] = React.useState('');
  const [reflection, setReflection] = React.useState('');
  const [reflectionSaved, setReflectionSaved] = React.useState(false);

  const isClientUser = currentUser?.app_role?.name === 'Client';

  React.useEffect(() => {
    async function loadClients() {
      if (isClientUser) {
        const response = await axios.get('/coaching/client-portal/me');
        setPortalClient(response.data);
        setClientId(response.data.id);
        const latestReflection =
          response.data.prep_briefs?.[0]?.client_reflection || '';
        setReflection(latestReflection);
        setReflectionSaved(Boolean(latestReflection));
        return;
      }

      const response = await axios.get('/coaching/clients');
      setClients(response.data);

      if (response.data.length > 0) {
        setClientId(response.data[0].id);
      }
    }

    loadClients();
  }, [currentUser?.email, isClientUser]);

  React.useEffect(() => {
    async function loadPortal() {
      if (!clientId) {
        return;
      }

      const response = await axios.get(`/coaching/client-portal/${clientId}`);
      setPortalClient(response.data);
      const latestReflection =
        response.data.prep_briefs?.[0]?.client_reflection || '';
      setReflection(latestReflection);
      setReflectionSaved(Boolean(latestReflection));
    }

    if (!isClientUser) {
      loadPortal();
    }
  }, [clientId, isClientUser]);

  async function toggleItem(item: { id: string; status: string }) {
    const nextStatus = item.status === 'done' ? 'in_progress' : 'done';
    setUpdatingItemId(item.id);

    const response = await axios.patch(
      `/coaching/client-portal/action-items/${item.id}`,
      { status: nextStatus },
    );

    setPortalClient((current) => {
      if (!current) {
        return current;
      }

      return {
        ...current,
        action_items: (current.action_items || []).map((currentItem) => {
          if (currentItem.id === item.id) {
            return response.data;
          }

          return currentItem;
        }),
      };
    });

    setUpdatingItemId('');
  }

  async function saveReflection() {
    const response = await axios.post('/coaching/client-portal/reflection', {
      clientId: portalClient?.id,
      reflection,
    });

    setPortalClient((current) => {
      if (!current) {
        return current;
      }

      const existingBriefs = current.prep_briefs || [];
      const otherBriefs = existingBriefs.filter((brief) => {
        return brief.id !== response.data.id;
      });

      return {
        ...current,
        prep_briefs: [response.data, ...otherBriefs],
      };
    });
    setReflectionSaved(true);
  }

  const openItems = (portalClient?.action_items || []).filter((item) => {
    return item.status !== 'done';
  });
  const finishedCount = (portalClient?.action_items || []).filter(
    (item) => item.status === 'done',
  ).length;
  const latestSession = portalClient?.sessions?.[0];

  return (
    <>
      <Head>
        <title>{getPageTitle('Client Portal')}</title>
      </Head>
      <SectionMain>
        <div className='mx-auto max-w-7xl'>
          {!isClientUser && (
            <Panel className='mb-4 p-6'>
              <label className='block text-xs font-semibold uppercase tracking-[0.22em] text-[#35b7a5]'>
                Preview as client
              </label>
              <select
                value={clientId}
                onChange={(event) => setClientId(event.target.value)}
                className='mt-3 w-full rounded-none border border-[#19192d]/10 bg-white px-4 py-3 text-[#19192d] outline-none focus:border-[#35b7a5] focus:ring-2 focus:ring-[#35b7a5]/15 md:w-96'
              >
                {clients.map((client) => (
                  <option key={client.id} value={client.id}>
                    {client.name}
                  </option>
                ))}
              </select>
            </Panel>
          )}

          {portalClient && (
            <div className='grid gap-6'>
              <div className='rounded-none border border-[#19192d]/10 bg-[#fffdf9] p-7'>
                <div className='grid gap-6 lg:grid-cols-[1fr_280px]'>
                  <div>
                    <p className='text-xs font-semibold uppercase tracking-[0.22em] text-[#35b7a5]'>
                      Client workspace
                    </p>
                    <h1 className='mt-2 text-2xl font-semibold text-[#19192d]'>
                      Hi, {portalClient.name}
                    </h1>
                    <p className='mt-3 max-w-3xl text-sm leading-6 text-[#72798a]'>
                      This is the shared space for your coaching work: notes
                      your coach approved, commitments you are working on, and
                      resources for the next session.
                    </p>
                  </div>

                  <div className='rounded-none border border-[#19192d]/10 bg-white p-6'>
                    <div className='flex items-center gap-2 text-sm font-semibold text-[#35b7a5]'>
                      <BaseIcon path={mdiCalendarClock} size={18} />
                      Next session
                    </div>
                    <p className='mt-2 text-lg font-semibold text-[#19192d]'>
                      {formatDate(portalClient.next_session_at)}
                    </p>
                    <p className='mt-2 text-sm leading-6 text-[#72798a]'>
                      Add your reflection below before the call.
                    </p>
                  </div>
                </div>
              </div>

              <div className='grid gap-6 md:grid-cols-3'>
                <Panel className='p-4'>
                  <p className='text-sm font-semibold text-[#72798a]'>
                    Open commitments
                  </p>
                  <p className='mt-2 text-2xl font-semibold text-[#19192d]'>
                    {openItems.length}
                  </p>
                </Panel>
                <Panel className='p-4'>
                  <p className='text-sm font-semibold text-[#72798a]'>
                    Completed
                  </p>
                  <p className='mt-2 text-2xl font-semibold text-[#19192d]'>
                    {finishedCount}
                  </p>
                </Panel>
                <Panel className='p-4'>
                  <p className='text-sm font-semibold text-[#72798a]'>
                    Shared resources
                  </p>
                  <p className='mt-2 text-2xl font-semibold text-[#19192d]'>
                    {portalClient.resources?.length || 0}
                  </p>
                </Panel>
              </div>

              <div className='grid gap-6 xl:grid-cols-[0.95fr_1.05fr]'>
                <div className='space-y-4'>
                  <Panel>
                    <div className='border-b border-[#19192d]/10 p-6'>
                      <div className='flex items-center gap-3'>
                        <span className='grid h-8 w-8 place-items-center rounded-none bg-[#fffdf9] text-[#35b7a5]'>
                          <BaseIcon path={mdiCheckCircleOutline} size={18} />
                        </span>
                        <div>
                          <h2 className='font-semibold text-[#19192d]'>
                            Commitments
                          </h2>
                          <p className='text-sm text-[#72798a]'>
                            Mark what you completed before the next session.
                          </p>
                        </div>
                      </div>
                    </div>
                    <div className='space-y-3 p-6'>
                      {(portalClient.action_items || []).map((item) => {
                        const isDone = item.status === 'done';

                        return (
                          <button
                            key={item.id}
                            type='button'
                            className={`flex w-full gap-3 rounded-none border p-6 text-left transition ${
                              isDone
                                ? 'border-[#35b7a5]/30 bg-[#fffdf9]'
                                : 'border-[#19192d]/10 bg-white hover:bg-[#fffdf9]'
                            }`}
                            disabled={updatingItemId === item.id}
                            onClick={() => toggleItem(item)}
                          >
                            <span
                              className={`mt-0.5 grid h-8 w-8 flex-none place-items-center rounded-none border ${
                                isDone
                                  ? 'border-[#35b7a5] bg-[#35b7a5] text-white'
                                  : 'border-[#19192d]/10 bg-white text-[#72798a]'
                              }`}
                            >
                              <BaseIcon
                                path={isDone ? mdiCheck : mdiFlagVariantOutline}
                                size={18}
                              />
                            </span>
                            <span>
                              <span className='block font-semibold text-[#19192d]'>
                                {item.title}
                              </span>
                              <span className='mt-1 block text-sm text-[#72798a]'>
                                {isDone
                                  ? 'Marked complete'
                                  : item.status.replace('_', ' ')}
                              </span>
                            </span>
                          </button>
                        );
                      })}
                    </div>
                  </Panel>

                  <Panel className='p-4'>
                    <div className='flex items-center gap-3'>
                      <span className='grid h-8 w-8 place-items-center rounded-none bg-[#fffdf9] text-[#35b7a5]'>
                        <BaseIcon path={mdiPencilOutline} size={18} />
                      </span>
                      <div>
                        <h2 className='font-semibold text-[#19192d]'>
                          Pre-session reflection
                        </h2>
                        <p className='text-sm text-[#72798a]'>
                          Share what changed since the last call.
                        </p>
                      </div>
                    </div>
                    <textarea
                      value={reflection}
                      onChange={(event) => {
                        setReflection(event.target.value);
                        setReflectionSaved(false);
                      }}
                      className='mt-4 min-h-[140px] w-full rounded-none border border-[#19192d]/10 bg-[#fffdf9] px-4 py-3 text-sm leading-6 text-[#19192d] outline-none focus:border-[#35b7a5] focus:ring-2 focus:ring-[#35b7a5]/15'
                      placeholder='What did you complete? What changed? What should we focus on next?'
                    />
                    <div className='mt-3 flex items-center justify-between gap-3'>
                      <p className='text-sm text-[#72798a]'>
                        {reflectionSaved
                          ? 'Reflection saved for this session.'
                          : 'Your coach will see this before the next call.'}
                      </p>
                      <button
                        type='button'
                        className='rounded-none bg-[#35b7a5] px-4 py-2 text-sm font-semibold text-white disabled:opacity-50'
                        disabled={!reflection.trim()}
                        onClick={saveReflection}
                      >
                        Save reflection
                      </button>
                    </div>
                  </Panel>
                </div>

                <div className='space-y-4'>
                  <Panel className='overflow-hidden'>
                    <div className='border-b border-[#19192d]/10 bg-[#fffdf9] p-6'>
                      <div className='flex items-center gap-3'>
                        <span className='grid h-8 w-8 place-items-center rounded-none bg-[#fffdf9] text-[#35b7a5]'>
                          <BaseIcon
                            path={mdiMessageReplyTextOutline}
                            size={18}
                          />
                        </span>
                        <div>
                          <h2 className='font-semibold text-[#19192d]'>
                            Shared notes
                          </h2>
                          <p className='text-sm text-[#72798a]'>
                            Coach-approved notes only.
                          </p>
                        </div>
                      </div>
                    </div>

                    <div className='space-y-3 p-6'>
                      {latestSession && (
                        <div className='rounded-none border border-[#19192d]/10 bg-white p-6'>
                          <p className='font-semibold text-[#19192d]'>
                            {latestSession.title}
                          </p>
                          <p className='mt-3 text-sm leading-6 text-[#72798a]'>
                            {latestSession.shared_client_notes}
                          </p>
                        </div>
                      )}
                      {(portalClient.sessions || []).slice(1).map((session) => (
                        <details
                          key={session.id}
                          className='rounded-none border border-[#19192d]/10 bg-white p-6'
                        >
                          <summary className='cursor-pointer font-semibold text-[#19192d]'>
                            {session.title}
                          </summary>
                          <p className='mt-3 text-sm leading-6 text-[#72798a]'>
                            {session.shared_client_notes}
                          </p>
                        </details>
                      ))}
                    </div>
                  </Panel>

                  <Panel>
                    <div className='border-b border-[#19192d]/10 p-6'>
                      <h2 className='font-semibold text-[#19192d]'>
                        Resources
                      </h2>
                    </div>
                    <div className='space-y-3 p-6'>
                      {(portalClient.resources || []).map((resource) => (
                        <a
                          key={resource.id}
                          href={resource.url}
                          className='flex items-center justify-between gap-6 rounded-none border border-[#19192d]/10 bg-white p-6 transition hover:bg-[#fffdf9]'
                        >
                          <div className='flex gap-3'>
                            <span className='grid h-8 w-8 place-items-center rounded-none bg-[#fffdf9] text-[#35b7a5]'>
                              <BaseIcon path={mdiBookOpenVariant} size={18} />
                            </span>
                            <div>
                              <p className='font-semibold text-[#19192d]'>
                                {resource.title}
                              </p>
                              <p className='mt-1 text-sm leading-6 text-[#72798a]'>
                                {resource.description}
                              </p>
                            </div>
                          </div>
                          <BaseIcon
                            path={mdiChevronRight}
                            size={18}
                            className='text-[#35b7a5]'
                          />
                        </a>
                      ))}
                    </div>
                  </Panel>
                </div>
              </div>
            </div>
          )}
        </div>
      </SectionMain>
    </>
  );
};

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

export default ClientPortal;
