import {
  mdiCheckCircleOutline,
  mdiCloudUploadOutline,
  mdiContentCopy,
  mdiFileDocumentEditOutline,
  mdiLightbulbOnOutline,
  mdiMicrophoneOutline,
  mdiSendOutline,
} from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import React from 'react';
import type { ReactElement } from 'react';
import BaseButton from '../components/BaseButton';
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 MemoryDraft = {
  title?: 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;
};

type Session = MemoryDraft & {
  id: string;
  status?: string;
  client?: Client;
};

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

function TextField({
  label,
  value,
  onChange,
  rows = 3,
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  rows?: number;
}) {
  return (
    <label className='block'>
      <span className='text-xs font-semibold uppercase tracking-[0.18em] text-[#b17a1e]'>
        {label}
      </span>
      <textarea
        value={value}
        rows={rows}
        onChange={(event) => onChange(event.target.value)}
        className='mt-2 w-full rounded-lg border border-[#19192d]/10 bg-[#fffdf9] px-3 py-2 text-sm leading-6 text-[#19192d] outline-none focus:border-[#35b7a5] focus:ring-2 focus:ring-[#35b7a5]/15'
      />
    </label>
  );
}

function StatusPill({ status }: { status?: string }) {
  const isShared = status === 'shared';

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

const emptyDraft: MemoryDraft = {
  title: '',
  ai_summary: '',
  key_topics: '',
  goals_discussed: '',
  blockers: '',
  commitments: '',
  homework: '',
  emotional_themes: '',
  important_quotes: '',
  follow_up_email: '',
  next_session_prep: '',
  private_coach_notes: '',
  shared_client_notes: '',
};

const SessionMemory = () => {
  const [clients, setClients] = React.useState<Client[]>([]);
  const [sessions, setSessions] = React.useState<Session[]>([]);
  const [clientId, setClientId] = React.useState('');
  const [transcript, setTranscript] = React.useState('');
  const [draft, setDraft] = React.useState<MemoryDraft>(emptyDraft);
  const [audioFile, setAudioFile] = React.useState<File | null>(null);
  const [isGenerating, setIsGenerating] = React.useState(false);
  const [isTranscribing, setIsTranscribing] = React.useState(false);
  const [isSaving, setIsSaving] = React.useState(false);
  const [notice, setNotice] = React.useState('');

  async function loadData() {
    const [clientsResponse, sessionsResponse] = await Promise.all([
      axios.get('/coaching/clients'),
      axios.get('/coaching/session-memory'),
    ]);
    setClients(clientsResponse.data);
    setSessions(sessionsResponse.data);

    if (!clientId && clientsResponse.data.length > 0) {
      setClientId(clientsResponse.data[0].id);
    }
  }

  React.useEffect(() => {
    loadData();
  }, []);

  function updateDraft(field: keyof MemoryDraft, value: string) {
    setDraft((current) => {
      return {
        ...current,
        [field]: value,
      };
    });
    setNotice('');
  }

  async function generateMemory() {
    setIsGenerating(true);

    try {
      const response = await axios.post('/coaching/session-memory/generate', {
        clientId,
        transcript,
      });
      setDraft({
        ...emptyDraft,
        ...response.data,
      });
      setNotice('Draft generated. Review and edit before saving.');
    } catch (error) {
      if (axios.isAxiosError(error)) {
        setNotice(
          error.response?.data?.message ||
            error.response?.data?.error ||
            'Memory generation failed.',
        );
      } else {
        setNotice('Memory generation failed.');
      }
    } finally {
      setIsGenerating(false);
    }
  }

  async function transcribeAudio() {
    if (!audioFile) {
      setNotice('Choose an audio file first.');
      return;
    }

    const formData = new FormData();
    formData.append('audio', audioFile);
    setIsTranscribing(true);

    try {
      const response = await axios.post(
        '/coaching/session-memory/transcribe',
        formData,
        {
          headers: { 'Content-Type': 'multipart/form-data' },
        },
      );
      setTranscript(response.data.text || '');
      setNotice('Audio transcribed. Review the transcript before generating memory.');
    } catch (error) {
      if (axios.isAxiosError(error)) {
        setNotice(
          error.response?.data?.message ||
            error.response?.data?.error ||
            'Audio transcription failed.',
        );
      } else {
        setNotice('Audio transcription failed.');
      }
    } finally {
      setIsTranscribing(false);
    }
  }

  async function saveMemory(shareWithClient: boolean) {
    setIsSaving(true);
    const response = await axios.post('/coaching/session-memory/save', {
      ...draft,
      clientId,
      transcript_notes: transcript,
      shareWithClient,
    });

    setSessions((current) => [response.data, ...current]);
    setDraft(emptyDraft);
    setTranscript('');
    setNotice(
      shareWithClient
        ? 'Session saved and shared with the client.'
        : 'Session saved as a coach draft.',
    );
    setIsSaving(false);
  }

  async function shareSession(session: Session) {
    const response = await axios.patch(`/coaching/sessions/${session.id}/share`, {
      shared_client_notes: session.shared_client_notes,
    });

    setSessions((current) =>
      current.map((currentSession) => {
        if (currentSession.id === session.id) {
          return response.data;
        }

        return currentSession;
      }),
    );
    setNotice('Session shared with the client.');
  }

  async function copyFollowUp() {
    await navigator.clipboard.writeText(draft.follow_up_email || '');
    setNotice('Follow-up copied.');
  }

  const hasDraft = Boolean(
    draft.title ||
      draft.ai_summary ||
      draft.follow_up_email ||
      draft.shared_client_notes,
  );

  return (
    <>
      <Head>
        <title>{getPageTitle('Session Memory')}</title>
      </Head>
      <SectionMain>
        <div className='mx-auto max-w-7xl'>
          <div className='mb-4 rounded-lg bg-[#19192d] p-5 text-white'>
            <div className='flex items-center gap-3 text-[#b17a1e]'>
              <BaseIcon path={mdiFileDocumentEditOutline} size={18} />
              <span className='text-xs font-semibold uppercase tracking-[0.22em]'>
                Session Memory
              </span>
            </div>
            <h1 className='mt-3 max-w-3xl text-xl font-semibold'>
              Turn rough notes into follow-up, commitments, and next-session
              prep.
            </h1>
            <p className='mt-2 max-w-3xl text-sm leading-6 text-[#fffdf9]'>
              Generate a structured draft, edit it as the coach, save it as a
              private draft, or share approved notes with the client portal.
            </p>
          </div>

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

          <div className='grid gap-4 xl:grid-cols-[0.8fr_1.2fr]'>
            <Panel className='p-4'>
              <p className='text-xs font-semibold uppercase tracking-[0.22em] text-[#b17a1e]'>
                Raw session input
              </p>
              <h2 className='mt-2 text-lg font-semibold text-[#19192d]'>
                Extract a session
              </h2>

              <label className='mb-2 mt-4 block text-sm font-semibold text-[#72798a]'>
                Client
              </label>
              <select
                value={clientId}
                onChange={(event) => setClientId(event.target.value)}
                className='w-full rounded-lg border border-[#19192d]/10 bg-white px-3 py-2 text-[#19192d] outline-none focus:border-[#35b7a5] focus:ring-2 focus:ring-[#35b7a5]/15'
              >
                {clients.map((client) => (
                  <option key={client.id} value={client.id}>
                    {client.name}
                  </option>
                ))}
              </select>

              <div className='mt-5 rounded-lg border border-[#19192d]/10 bg-[#fffdf9] p-3'>
                <div className='flex items-center gap-2 text-sm font-semibold text-[#19192d]'>
                  <BaseIcon path={mdiMicrophoneOutline} size={18} />
                  Audio transcription
                </div>
                <label className='mt-3 flex cursor-pointer items-center justify-between gap-3 rounded-lg border border-dashed border-[#19192d]/15 bg-white px-3 py-3 text-sm text-[#72798a]'>
                  <span className='truncate'>
                    {audioFile ? audioFile.name : 'Choose an audio file'}
                  </span>
                  <span className='inline-flex items-center gap-2 rounded-full bg-[#f3fbf8] px-3 py-1 text-xs font-semibold text-[#257f73]'>
                    <BaseIcon path={mdiCloudUploadOutline} size={16} />
                    Upload
                  </span>
                  <input
                    type='file'
                    accept='audio/*'
                    className='hidden'
                    onChange={(event) => {
                      const file = event.target.files?.[0] || null;
                      setAudioFile(file);
                      setNotice('');
                    }}
                  />
                </label>
                <button
                  type='button'
                  className='mt-3 inline-flex items-center gap-2 rounded-full bg-[#35b7a5] px-3 py-1.5 text-sm font-semibold text-white disabled:opacity-50'
                  disabled={isTranscribing || !audioFile}
                  onClick={transcribeAudio}
                >
                  <BaseIcon path={mdiMicrophoneOutline} size={18} />
                  {isTranscribing ? 'Transcribing...' : 'Transcribe audio'}
                </button>
              </div>

              <label className='mb-2 mt-5 block text-sm font-semibold text-[#72798a]'>
                Transcript or raw notes
              </label>
              <textarea
                value={transcript}
                onChange={(event) => setTranscript(event.target.value)}
                className='min-h-[220px] w-full rounded-lg border border-[#19192d]/10 bg-[#fffdf9] px-3 py-2 leading-6 text-[#19192d] outline-none focus:border-[#35b7a5] focus:ring-2 focus:ring-[#35b7a5]/15'
                placeholder='Paste session transcript, coach notes, commitments, blockers, or a rough debrief...'
              />
              <div className='mt-5'>
                <BaseButton
                  label={isGenerating ? 'Generating...' : 'Generate memory'}
                  color='info'
                  disabled={isGenerating || !clientId || !transcript.trim()}
                  onClick={generateMemory}
                />
              </div>
            </Panel>

            <div className='space-y-4'>
              <Panel className='p-4'>
                <div className='flex items-start justify-between gap-4'>
                  <div>
                    <p className='text-xs font-semibold uppercase tracking-[0.22em] text-[#b17a1e]'>
                      Coach review
                    </p>
                    <h2 className='mt-2 text-lg font-semibold text-[#19192d]'>
                      Edit the final memory
                    </h2>
                  </div>
                  <span className='rounded-full bg-[#fbf8f1] px-3 py-1 text-xs font-semibold text-[#b17a1e]'>
                    Not shared until approved
                  </span>
                </div>

                {hasDraft ? (
                  <div className='mt-4 grid gap-4'>
                    <label className='block'>
                      <span className='text-xs font-semibold uppercase tracking-[0.18em] text-[#b17a1e]'>
                        Title
                      </span>
                      <input
                        value={draft.title || ''}
                        onChange={(event) =>
                          updateDraft('title', event.target.value)
                        }
                        className='mt-2 w-full rounded-lg border border-[#19192d]/10 bg-[#fffdf9] px-3 py-2 text-sm text-[#19192d] outline-none focus:border-[#35b7a5] focus:ring-2 focus:ring-[#35b7a5]/15'
                      />
                    </label>

                    <TextField
                      label='Summary'
                      value={draft.ai_summary || ''}
                      onChange={(value) => updateDraft('ai_summary', value)}
                      rows={4}
                    />
                    <TextField
                      label='Commitments'
                      value={draft.commitments || ''}
                      onChange={(value) => updateDraft('commitments', value)}
                    />
                    <TextField
                      label='Homework'
                      value={draft.homework || ''}
                      onChange={(value) => updateDraft('homework', value)}
                    />
                    <TextField
                      label='Shared client notes'
                      value={draft.shared_client_notes || ''}
                      onChange={(value) =>
                        updateDraft('shared_client_notes', value)
                      }
                      rows={4}
                    />
                    <TextField
                      label='Follow-up email'
                      value={draft.follow_up_email || ''}
                      onChange={(value) => updateDraft('follow_up_email', value)}
                      rows={4}
                    />
                    <TextField
                      label='Next-session prep'
                      value={draft.next_session_prep || ''}
                      onChange={(value) =>
                        updateDraft('next_session_prep', value)
                      }
                    />
                    <TextField
                      label='Private coach notes'
                      value={draft.private_coach_notes || ''}
                      onChange={(value) =>
                        updateDraft('private_coach_notes', value)
                      }
                    />

                    <div className='flex flex-wrap gap-3'>
                      <button
                        type='button'
                        className='inline-flex items-center gap-2 rounded-full bg-[#19192d] px-3 py-1.5 text-sm font-semibold text-white disabled:opacity-50'
                        disabled={isSaving}
                        onClick={() => saveMemory(false)}
                      >
                        <BaseIcon path={mdiCheckCircleOutline} size={18} />
                        Save coach draft
                      </button>
                      <button
                        type='button'
                        className='inline-flex items-center gap-2 rounded-full bg-[#35b7a5] px-3 py-1.5 text-sm font-semibold text-white disabled:opacity-50'
                        disabled={isSaving}
                        onClick={() => saveMemory(true)}
                      >
                        <BaseIcon path={mdiSendOutline} size={18} />
                        Save and share
                      </button>
                      <button
                        type='button'
                        className='inline-flex items-center gap-2 rounded-full border border-[#19192d]/10 bg-white px-3 py-1.5 text-sm font-semibold text-[#19192d]'
                        onClick={copyFollowUp}
                      >
                        <BaseIcon path={mdiContentCopy} size={18} />
                        Copy follow-up
                      </button>
                    </div>
                  </div>
                ) : (
                  <div className='mt-4 rounded-lg border border-dashed border-[#19192d]/10 bg-[#fffdf9] p-4'>
                    <BaseIcon
                      path={mdiLightbulbOnOutline}
                      size={22}
                      className='text-[#b17a1e]'
                    />
                    <p className='mt-4 leading-6 text-[#72798a]'>
                      Generate memory from raw notes. The editable draft will
                      appear here before anything is saved or shared.
                    </p>
                  </div>
                )}
              </Panel>

              <Panel>
                <div className='border-b border-[#19192d]/10 p-5'>
                  <h2 className='text-lg font-semibold text-[#19192d]'>
                    Recent memories
                  </h2>
                </div>
                <div className='divide-y divide-[#19192d]/10'>
                  {sessions.map((session) => (
                    <div key={session.id} className='p-5'>
                      <div className='flex items-start justify-between gap-4'>
                        <div>
                          <div className='flex flex-wrap items-center gap-2'>
                            <p className='font-semibold text-[#19192d]'>
                              {session.title}
                            </p>
                            <StatusPill status={session.status} />
                          </div>
                          <p className='mt-1 text-sm text-[#72798a]'>
                            {session.client?.name}
                          </p>
                        </div>
                        {session.status !== 'shared' && (
                          <button
                            type='button'
                            className='inline-flex items-center gap-2 rounded-full bg-[#35b7a5] px-3 py-1.5 text-sm font-semibold text-white'
                            onClick={() => shareSession(session)}
                          >
                            <BaseIcon path={mdiSendOutline} size={18} />
                            Share
                          </button>
                        )}
                      </div>
                      <p className='mt-3 leading-6 text-[#72798a]'>
                        {session.ai_summary}
                      </p>
                      <p className='mt-3 text-sm font-semibold text-[#35b7a5]'>
                        {session.key_topics}
                      </p>
                    </div>
                  ))}
                </div>
              </Panel>
            </div>
          </div>
        </div>
      </SectionMain>
    </>
  );
};

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

export default SessionMemory;
