import {
  mdiArrowLeft,
  mdiCheckCircleOutline,
  mdiFileDocumentEditOutline,
  mdiSendOutline,
  mdiTrashCanOutline,
} from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import { useRouter } from 'next/router';
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';

type Client = {
  id: string;
  name: string;
};

type Session = {
  id: string;
  title?: string;
  status?: string;
  client?: Client;
  session_at?: string;
  transcript_notes?: string;
  ai_summary?: string;
  key_topics?: string;
  goals_discussed?: string;
  blockers?: string;
  commitments?: string;
  homework?: string;
  emotional_themes?: string;
  important_quotes?: string;
  follow_up_email?: string;
  next_session_prep?: string;
  private_coach_notes?: string;
  shared_client_notes?: string;
  audio_url?: string;
  audio_filename?: string;
};

type TranscriptTurn = {
  speaker: string;
  text: 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 StatusPill({ status }: { status?: string }) {
  const isShared = status === 'shared';

  return (
    <span
      className={`rounded-none px-3 py-1 text-xs font-semibold ${
        isShared ? 'bg-[#fffdf9] text-[#35b7a5]' : 'bg-[#fffdf9] text-[#35b7a5]'
      }`}
    >
      {isShared ? 'Shared' : 'Coach draft'}
    </span>
  );
}

function parseTranscriptTurns(value?: string) {
  const turns: TranscriptTurn[] = [];

  String(value || '')
    .split('\n')
    .map((line) => line.trim())
    .filter(Boolean)
    .forEach((line) => {
      const match = line.match(/^([A-ZА-Я][\wА-Яа-я -]{0,30}):\s*(.+)$/u);

      if (match) {
        turns.push({
          speaker: match[1],
          text: match[2],
        });
        return;
      }

      const previousTurn = turns[turns.length - 1];
      if (previousTurn) {
        previousTurn.text = `${previousTurn.text} ${line}`;
        return;
      }

      turns.push({
        speaker: 'Transcript',
        text: line,
      });
    });

  return turns;
}

function TranscriptConversation({ value }: { value?: string }) {
  const turns = parseTranscriptTurns(value);

  if (turns.length === 0) {
    return (
      <p className='rounded-none border border-dashed border-[#19192d]/10 bg-[#fffdf9] p-4 text-sm text-[#72798a]'>
        No transcript saved for this session.
      </p>
    );
  }

  return (
    <div className='space-y-3'>
      {turns.map((turn, index) => (
        <div
          key={`${turn.speaker}-${index}-${turn.text.slice(0, 18)}`}
          className='grid gap-3 border border-[#19192d]/10 bg-[#fffdf9] p-4 md:grid-cols-[72px_1fr]'
        >
          <div className='text-xs font-semibold uppercase tracking-[0.18em] text-[#35b7a5]'>
            {turn.speaker}
          </div>
          <p className='text-sm leading-6 text-[#19192d]'>{turn.text}</p>
        </div>
      ))}
    </div>
  );
}

function displayDateTime(value?: string) {
  if (!value) {
    return 'No date';
  }

  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return value;
  }

  return date.toLocaleString(undefined, {
    month: 'short',
    day: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
  });
}

function DetailBlock({ label, value }: { label: string; value?: string }) {
  if (!value) {
    return null;
  }

  return (
    <div className='border-t border-[#19192d]/10 pt-4'>
      <p className='text-xs font-semibold uppercase tracking-[0.18em] text-[#35b7a5]'>
        {label}
      </p>
      <p className='mt-2 whitespace-pre-wrap text-sm leading-6 text-[#72798a]'>
        {value}
      </p>
    </div>
  );
}

const SessionMemoryView = () => {
  const router = useRouter();
  const [session, setSession] = React.useState<Session | null>(null);
  const [notice, setNotice] = React.useState('');
  const [audioSourceUrl, setAudioSourceUrl] = React.useState('');
  const [isDeleting, setIsDeleting] = React.useState(false);
  const [isSharing, setIsSharing] = React.useState(false);

  React.useEffect(() => {
    if (!router.isReady || typeof router.query.sessionId !== 'string') {
      return;
    }

    loadSession(router.query.sessionId);
  }, [router.isReady, router.query.sessionId]);

  React.useEffect(() => {
    if (!session?.audio_url) {
      setAudioSourceUrl('');
      return;
    }

    let revoked = false;
    let objectUrl = '';

    axios
      .get(`/coaching/sessions/${session.id}/audio`, {
        responseType: 'blob',
      })
      .then((response) => {
        objectUrl = URL.createObjectURL(response.data);

        if (revoked) {
          URL.revokeObjectURL(objectUrl);
          return;
        }

        setAudioSourceUrl(objectUrl);
      })
      .catch(() => {
        setNotice('Audio file could not be loaded.');
      });

    return () => {
      revoked = true;

      if (objectUrl) {
        URL.revokeObjectURL(objectUrl);
      }
    };
  }, [session?.id, session?.audio_url]);

  async function loadSession(sessionId: string) {
    const response = await axios.get(`/coaching/sessions/${sessionId}`);
    setSession(response.data);
  }

  async function shareSession() {
    if (!session) {
      return;
    }

    setIsSharing(true);
    try {
      const response = await axios.patch(`/coaching/sessions/${session.id}/share`, {
        shared_client_notes: session.shared_client_notes,
      });
      setSession(response.data);
      setNotice('Session shared with the client.');
    } finally {
      setIsSharing(false);
    }
  }

  async function deleteSession() {
    if (!session) {
      return;
    }

    const confirmed = window.confirm(
      `Delete "${session.title || 'Client session'}"? This cannot be undone.`,
    );

    if (!confirmed) {
      return;
    }

    setIsDeleting(true);
    try {
      await axios.delete(`/coaching/sessions/${session.id}`);
      await router.push('/session-memory');
    } finally {
      setIsDeleting(false);
    }
  }

  return (
    <>
      <Head>
        <title>{getPageTitle(session?.title || 'Session')}</title>
      </Head>
      <SectionMain>
        <div className='mx-auto max-w-7xl'>
          <button
            type='button'
            className='mb-6 inline-flex items-center gap-2 text-sm font-semibold text-[#72798a] hover:text-[#19192d]'
            onClick={() => router.push('/session-memory')}
          >
            <BaseIcon path={mdiArrowLeft} size={18} />
            Session archive
          </button>

          <div className='mb-4 flex flex-col justify-between gap-4 rounded-none bg-[#19192d] p-7 text-white md:flex-row md:items-end'>
            <div>
              <div className='flex items-center gap-3 text-[#35b7a5]'>
                <BaseIcon path={mdiFileDocumentEditOutline} size={18} />
                <span className='text-xs font-semibold uppercase tracking-[0.22em]'>
                  Session
                </span>
              </div>
              <h1 className='mt-3 max-w-3xl text-xl font-semibold'>
                {session?.title || 'Client session'}
              </h1>
              <p className='mt-2 max-w-3xl text-sm leading-6 text-[#fffdf9]'>
                {session
                  ? `${session.client?.name || 'No client'} · ${displayDateTime(
                      session.session_at,
                    )}`
                  : 'Loading session...'}
              </p>
            </div>
            {session && <StatusPill status={session.status} />}
          </div>

          {notice && (
            <div className='mb-4 rounded-none border border-[#35b7a5]/20 bg-[#fffdf9] px-4 py-3 text-sm font-semibold text-[#35b7a5]'>
              {notice}
            </div>
          )}

          {session ? (
            <div className='grid gap-6 lg:grid-cols-[1.2fr_0.8fr]'>
              <Panel className='p-5'>
                <p className='text-xs font-semibold uppercase tracking-[0.22em] text-[#35b7a5]'>
                  Transcript
                </p>
                <div className='mt-4'>
                  <TranscriptConversation value={session.transcript_notes} />
                </div>
              </Panel>

              <div className='space-y-6'>
                <Panel className='p-5'>
                  <div className='flex flex-wrap gap-3'>
                    {session.status !== 'shared' && (
                      <button
                        type='button'
                        className='inline-flex items-center gap-2 rounded-none bg-[#35b7a5] px-4 py-2 text-sm font-semibold text-white disabled:opacity-50'
                        disabled={isSharing}
                        onClick={shareSession}
                      >
                        <BaseIcon path={mdiSendOutline} size={18} />
                        {isSharing ? 'Sharing...' : 'Share with client'}
                      </button>
                    )}
                    <button
                      type='button'
                      className='inline-flex items-center gap-2 rounded-none border border-[#19192d]/10 bg-white px-4 py-2 text-sm font-semibold text-[#19192d] disabled:opacity-50'
                      disabled={isDeleting}
                      onClick={deleteSession}
                    >
                      <BaseIcon path={mdiTrashCanOutline} size={18} />
                      {isDeleting ? 'Deleting...' : 'Delete session'}
                    </button>
                  </div>
                </Panel>

                {session.audio_url && (
                  <Panel className='p-5'>
                    <p className='text-xs font-semibold uppercase tracking-[0.22em] text-[#35b7a5]'>
                      Audio recording
                    </p>
                    {audioSourceUrl ? (
                      <audio
                        className='mt-4 w-full'
                        controls
                        src={audioSourceUrl}
                      />
                    ) : (
                      <p className='mt-4 text-sm text-[#72798a]'>
                        Loading audio...
                      </p>
                    )}
                    <p className='mt-2 text-xs text-[#72798a]'>
                      {session.audio_filename || 'Session audio'}
                    </p>
                  </Panel>
                )}

                <Panel className='space-y-4 p-5'>
                  <div>
                    <p className='text-xs font-semibold uppercase tracking-[0.22em] text-[#35b7a5]'>
                      Coach memory
                    </p>
                    <p className='mt-2 text-sm leading-6 text-[#72798a]'>
                      {session.ai_summary || 'No summary saved.'}
                    </p>
                  </div>
                  <DetailBlock label='Key topics' value={session.key_topics} />
                  <DetailBlock label='Goals discussed' value={session.goals_discussed} />
                  <DetailBlock label='Blockers' value={session.blockers} />
                  <DetailBlock label='Commitments' value={session.commitments} />
                  <DetailBlock label='Homework' value={session.homework} />
                  <DetailBlock label='Emotional themes' value={session.emotional_themes} />
                  <DetailBlock label='Important quotes' value={session.important_quotes} />
                  <DetailBlock label='Shared client notes' value={session.shared_client_notes} />
                  <DetailBlock label='Follow-up email' value={session.follow_up_email} />
                  <DetailBlock label='Next-session prep' value={session.next_session_prep} />
                  <DetailBlock label='Private coach notes' value={session.private_coach_notes} />
                </Panel>
              </div>
            </div>
          ) : (
            <Panel className='p-5'>
              <p className='text-sm text-[#72798a]'>Loading session...</p>
            </Panel>
          )}
        </div>
      </SectionMain>
    </>
  );
};

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

export default SessionMemoryView;
