import React, { Component, ChangeEvent } from 'react';
import FormExtended, { FormExtendedProps, FormExtendedState } from '@hubleto/react-ui/ext/FormExtended';
import TableContacts from '@hubleto/apps/Contacts/Components/TableContacts';
import TableRecipients from '@hubleto/apps/Campaigns/Components/TableRecipients';
import TableClicks from '@hubleto/apps/Campaigns/Components/TableClicks';
import TableTasks from '@hubleto/apps/Tasks/Components/TableTasks';
import request from '@hubleto/react-ui/core/Request';
import InputJsonKeyValue from "@hubleto/react-ui/core/Inputs/JsonKeyValue";
import ModalForm from '@hubleto/react-ui/core/ModalForm';
import CampaignFormActivity, { CampaignFormActivityProps, CampaignFormActivityState } from './CampaignFormActivity';
import moment, { Moment } from "moment";
import Calendar from '../../Calendar/Components/Calendar';
import { updateFormWorkflowByTag } from '@hubleto/react-ui/ext/ErpWorkflowSelector';
import FormItem from '@hubleto/apps/Orders/Components/FormItem';

export interface FormCampaignProps extends FormExtendedProps {}
export interface FormCampaignState extends FormExtendedState {
  testEmailVariables?: any,
  testEmailSendResult?: any,
  launchResult?: any,
  campaignTestInfo?: any,
  campaignLaunchInfo?: any,
  recipients?: any,
  showIdActivity: number,
  activityTime: string,
  activityDate: string,
  activitySubject: string,
  activityAllDay: boolean,
  recentlyContactedPeriod?: number,
  subTab: string,
}

export default class FormCampaign<P, S> extends FormExtended<FormCampaignProps, FormCampaignState> {
  static defaultProps: any = {
    ...FormExtended.defaultProps,
    model: 'Hubleto/App/Community/Campaigns/Models/Campaign',
    renderWorkflowUi: true,
    renderOwnerManagerUi: true,
  };

  props: FormCampaignProps;
  state: FormCampaignState;

  translationContext: string = 'Hubleto\\App\\Community\\Campaigns\\Loader';
  translationContextInner: string = 'Components\\FormCampaign';

  parentApp: string = 'Hubleto/App/Community/Campaigns';

  refTestEmailRecipientInput: any = React.createRef();
  refLogActivityInput: any = React.createRef();
  refActivityModal: any = React.createRef();
  refActivityForm: any = React.createRef();
  refEmails: any = React.createRef();
  refTableRecipients: any = React.createRef();

  constructor(props: FormCampaignProps) {
    super(props);
    this.state = this.getStateFromProps(props);
  }

  getStateFromProps(props: FormCampaignProps) {
    return {
      ...super.getStateFromProps(props),
      showIdActivity: 0,
      activityTime: '',
      activityDate: '',
      activitySubject: '',
      activityAllDay: false,
      campaignTestInfo: null,
      campaignLaunchInfo: null,
      recentlyContactedPeriod: 1,
      tabs: [
        { uid: 'default', title: <b>{this.translate('Campaign')}</b> },
        { uid: 'documents', title: this.translate('Documents') },
        { uid: 'calendar', title: this.translate('Calendar') },
        { uid: 'contacts', title: this.translate('Contacts') },
        { uid: 'recipients', title: this.translate('Recipients') },
        { uid: 'mail', title: this.translate('Mail'), subTabs: [
          { uid: 'content', title: this.translate('Content') },
          { uid: 'test', title: this.translate('Test') },
          { uid: 'launch', title: this.translate('Launch') },
          { uid: 'clicks', title: this.translate('Clicks') },
        ] },
        { uid: 'call', title: this.translate('Call') },
        { uid: 'tasks', title: this.translate('Tasks'), showCountFor: 'TASKS' },
        { uid: 'timeline', icon: 'fas fa-timeline', position: 'right' },
        ...this.getCustomTabs()
      ],
      subTab: '',
    };
  }

  getRecordFormUrl(): string {
    return 'campaigns/' + (this.state.record.id > 0 ? this.state.record.id : 'add');
  }

  contentClassName(): string
  {
    return this.state.record.is_closed ? 'bg-slate-100' : '';
  }

  removeRecipient(email: string) {
    this.setState({campaignTestInfo: null}, () => {
      request.post(
        'campaigns/api/remove-recipient-from-campaign',
        {
          idCampaign: this.state.record.id,
          email: email,
        },
        {},
        (data: any) => {
          this.updateCampaignTestInfo();
        }
      );
    });
  }

  removeRecipients(emails: Array<string>) {
    this.setState({campaignTestInfo: null}, () => {
      request.post(
        'campaigns/api/remove-recipient-from-campaign',
        {
          idCampaign: this.state.record.id,
          emails: emails,
        },
        {},
        (data: any) => {
          this.updateCampaignTestInfo();
        }
      );
    });
  }

  updateCampaignTestInfo() {
    this.setState({campaignTestInfo: null}, () => {
      request.post(
        'campaigns/api/get-campaign-test-info',
        {
          idCampaign: this.state.record.id,
          recentlyContactedPeriod: this.state.recentlyContactedPeriod,
        },
        {},
        (data: any) => {
          this.setState({campaignTestInfo: data});
        }
      );
    });
  }

  updateCampaignLaunchInfo() {
    this.setState({campaignLaunchInfo: null}, () => {
      request.post(
        'campaigns/api/get-campaign-launch-info',
        {
          idCampaign: this.state.record.id,
          recentlyContactedPeriod: this.state.recentlyContactedPeriod,
        },
        {},
        (data: any) => {
          this.setState({campaignLaunchInfo: data});
        }
      );
    });

  }

  onTabChange() {
    super.onTabChange();

    const tabUid = this.state.activeTabUid;
    switch (tabUid) {
      case 'mail.test':
        this.updateCampaignTestInfo();
      break;
      case 'mail.launch':
        this.updateCampaignLaunchInfo();
      break;
    }
  }

  renderTitle(): JSX.Element {
    return <>
      <small>{this.translate("Campaign")}</small>
      <h2>{this.state.record.name ?? '-'}</h2>
    </>;
  }

  logCompletedActivity() {
    request.get(
      'campaigns/api/log-activity',
      {
        idCampaign: this.state.record.id,
        activity: this.refLogActivityInput.current.value,
      },
      (result: any) => {
        this.loadRecord();
        this.refLogActivityInput.current.value = '';
      }
    );
  }

  scheduleActivity() {
    this.setState({
      showIdActivity: -1,
      activityDate: moment().add(1, 'week').format('YYYY-MM-DD'),
      activityTime: moment().add(1, 'week').format('H:00:00'),
      activitySubject: this.refLogActivityInput.current.value,
      activityAllDay: false,
    } as FormCampaignState);
  }

  renderTab(tabUid: string) {
    const R = this.state.record;

    switch (tabUid) {
      case 'default':
        return <>
          <div className='w-full flex flex-col md:flex-row gap-2'>
            <div className='flex-1 border-r border-gray-100'>
              {this.inputWrapper('name')}
              {this.inputWrapper('type')}
              {this.inputWrapper('target_audience')}
              {this.inputWrapper('goal')}
              {this.inputWrapper('notes')}
              {this.inputWrapper('id_mail_account')}
              {this.inputWrapper('id_mail_template')}
              {this.inputWrapper('reply_to')}
              {this.inputWrapper('is_approved')}
              {/* {this.inputWrapper('mail_body')} */}
            </div>
            <div className='flex-1'>
              <div className='w-full flex gap-2'>
                {this.inputWrapper('utm_source')}
                {this.inputWrapper('utm_campaign')}
              </div>
              <div className='w-full flex gap-2'>
                {this.inputWrapper('utm_term')}
                {this.inputWrapper('utm_content')}
              </div>
              {this.inputWrapper('color')}
              {this.inputWrapper('datetime_created')}
              {this.inputWrapper('uid')}
            </div>
          </div>
        </>;
      break

      case 'documents':
        let iframeUrl = '';

        try {
          let url = new URL(R.shared_folder ?? '');
          
          if (
            url.hostname == 'drive.google.com'
            && url.pathname.indexOf('/drive/folders') == 0
          ) {

            // for Google Drive, replacing
            // https://drive.google.com/drive/folders/FOLDER_ID
            // with https://drive.google.com/embeddedfolderview?id=FOLDER_ID
            // makes the folder embeddable

            iframeUrl = 'https://drive.google.com/embeddedfolderview'
              + '?id=' + url.pathname.replace('/drive/folders/', '')
              + '&authuser=0'
            ;

          } else {
            iframeUrl = R.shared_folder ?? '';
          }
        } catch (e) {
        }

        return <div className='flex flex-col gap-2 h-full'>
          {this.inputWrapper('shared_folder')}
          <iframe
            className='w-full h-full shadow-sm'
            src={iframeUrl}
          ></iframe>
        </div>;
      break;

      case 'calendar':
        //@ts-ignore
        const tmpCalendarSmall = <Calendar
          onCreateCallback={() => this.loadRecord()}
          readonly={R.is_closed}
          initialView='dayGridMonth'
          headerToolbar={{ start: 'title', center: '', end: 'prev,today,next' }}
          eventsEndpoint={globalThis.hubleto.config.projectUrl + '/calendar/api/get-calendar-events?calendar=campaigns&idCampaign=' + R.id}
          onDateClick={(date, time, info) => {
            this.setState({
              activityDate: date,
              activityTime: time,
              activityAllDay: false,
              showIdActivity: -1,
            } as FormCampaignState);
          }}
          onEventClick={(info) => {
            this.setState({
              showIdActivity: parseInt(info.event.id),
            } as FormCampaignState);
            info.jsEvent.preventDefault();
          }}
        ></Calendar>;

        const recentActivitiesAndCalendar = <div className='card card-body flex flex-col gap-2'>
          <div>
            {tmpCalendarSmall}
          </div>
          <div>
            <div className="hubleto component input"><div className="input-element w-full flex gap-2">
              <input
                className="w-full bg-blue-50 border border-blue-800 p-1 text-blue-800 placeholder-blue-300"
                placeholder={this.translate('Type recent activity here')}
                ref={this.refLogActivityInput}
                onKeyUp={(event: any) => {
                  if (event.keyCode == 13) {
                    if (event.shiftKey) {
                      this.scheduleActivity();
                    } else {
                      this.logCompletedActivity();
                    }
                  }
                }}
                onChange={(event: ChangeEvent<HTMLInputElement>) => {
                  this.refLogActivityInput.current.value = event.target.value;
                }}
              />
            </div></div>
            <div className='mt-2'>
              <button onClick={() => {this.logCompletedActivity()}} className="btn btn-blue-outline btn-small w-full">
                <span className="icon"><i className="fas fa-check"></i></span>
                <span className="text">{this.translate('Log completed activity')}</span>
                <span className="shortcut">Enter</span>
              </button>
              <button onClick={() => {this.scheduleActivity()}} className="btn btn-small w-full btn-blue-outline">
                <span className="icon"><i className="fas fa-clock"></i></span>
                <span className="text">{this.translate('Schedule activity')}</span>
                <span className="shortcut">Shift+Enter</span>
              </button>
            </div>
            {this.divider(this.translate('Most recent activities'))}
            {R.ACTIVITIES ? <div className="list">{R.ACTIVITIES.reverse().slice(0, 7).map((item, index) => {
              return <>
                <button key={index} className={"btn btn-small btn-transparent btn-list-item " + (item.completed ? "bg-green-50" : "bg-red-50")}
                  onClick={() => this.setState({showIdActivity: item.id} as FormCampaignState)}
                >
                  <span className="icon">{item.date_start} {item.time_start}<br/>@{item['_LOOKUP[id_owner]']}</span>
                  <span className="text">
                    {item.subject}
                    {item.completed ? null : <div className="text-red-800">{this.translate('Not completed yet')}</div>}
                  </span>
                </button>
              </>
            })}</div> : null}
          </div>
        </div>;

        //@ts-ignore
        const tmpCalendarLarge = <Calendar
          onCreateCallback={() => this.loadRecord()}
          readonly={R.is_closed}
          initialView='timeGridWeek'
          views={"timeGridDay,timeGridWeek,dayGridMonth,listYear"}
          eventsEndpoint={globalThis.hubleto.config.projectUrl + '/calendar/api/get-calendar-events?calendar=campaigns&idCampaign=' + R.id}
          onDateClick={(date, time, info) => {
            this.setState({
              activityDate: date,
              activityTime: time,
              activityAllDay: false,
              showIdActivity: -1,
            } as FormCampaignState);
          }}
          onEventClick={(info) => {
            this.setState({
              showIdActivity: parseInt(info.event.id),
            } as FormCampaignState);
            info.jsEvent.preventDefault();
          }}
        ></Calendar>;

        return <>
          <div className='flex gap-2 mt-2'>
            <div className='flex-2 w-2/3'>
              {tmpCalendarLarge}
            </div>
            <div className='flex-1 w-1/3'>
              {this.state.id > 0 ? recentActivitiesAndCalendar : null}
            </div>
          </div>
          {this.state.showIdActivity == 0 ? null :
            <ModalForm
              ref={this.refActivityModal}
              form={this.refActivityForm}
              uid='activity_form'
              isOpen={true}
              type='right'
            >
              <CampaignFormActivity
                modal={this.refActivityModal}
                ref={this.refActivityForm}
                id={this.state.showIdActivity}
                isInlineEditing={true}
                description={{
                  defaultValues: {
                    id_campaign: R.id,
                    date_start: this.state.activityDate,
                    time_start: this.state.activityTime == "00:00:00" ? null : this.state.activityTime,
                    date_end: this.state.activityDate,
                    all_day: this.state.activityAllDay,
                    subject: this.state.activitySubject,
                  }
                }}
                idCustomer={R.id_customer}
                onClose={() => { this.setState({ showIdActivity: 0 } as FormCampaignState) }}
                onSaveCallback={(form: CampaignFormActivity<CampaignFormActivityProps, CampaignFormActivityState>, saveResponse: any) => {
                  if (saveResponse.status == "success") {
                    this.setState({ showIdActivity: 0 } as FormCampaignState);
                  }
                }}
              ></CampaignFormActivity>
            </ModalForm>
          }
        </>;
      break;

      case 'contacts':
        return <div>
          <div>
            { this.translate('Select contacts which will be added as recipients') }
          </div>
          <TableContacts
            tag={"table_campaign_contact"}
            parentForm={this}
            uid={this.props.uid + "_table_campaign_contact"}
            selectionMode='multiple'
            readonly={true}
            descriptionSource='both'
            //@ts-ignore
            description={{ui: {showHeader: false}}}
            idCustomer={0}
            selection={R && R.RECIPIENTS ? R.RECIPIENTS.map((item) => { return { id: item.id_contact } }) : null}
            onSelectionChange={(table: any) => {
              request.post(
                'campaigns/api/save-recipients-from-contacts',
                {
                  idCampaign: this.state.record.id,
                  contactIds: table.state.selection.map((item) => item.id)
                },
                {},
                (result: any) => {
                  this.setState({record: {...R, RECIPIENTS: result}});
                }
              );
            }}
          />
        </div>;
      break;

      case 'call':
        return <>
          {this.inputWrapper('call_script')}
        </>
      break;

      case 'mail.content':
        return <>
          {this.inputWrapper('mail_subject')}
          {this.inputWrapper('mail_body')}
        </>
      break;

      case 'mail.test':
        return <div className='flex gap-2'>
          <div className='card flex-1'>
            <div className='card-header'>{ this.translate('Analysis & warnings') }</div>
            <div className='card-body'>
              {this.state.campaignTestInfo ? <>
                {this.state.campaignTestInfo.warnings.length == 0 ? 
                  <div className='alert alert-success'>
                    <i className='fas fa-check mr-2'></i>
                    { this.translate('No warnings') }
                  </div>
                :
                  this.state.campaignTestInfo.warnings.map((item, key) => {
                    return <div key={key} className='alert alert-warning'>{item}</div>;
                  })
                }
                <div className='flex gap-1'>
                  <b className='flex gap-1 items-center'>Recipients contacted in last <input
                    type='number'
                    className='w-12'
                    value={this.state.recentlyContactedPeriod}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                      this.setState({recentlyContactedPeriod: event.target.value}, () => {
                        this.updateCampaignTestInfo();
                      });
                    }}
                  ></input> months</b>
                  <button
                    className='btn btn-delete-outline btn-small'
                    onClick={() => {
                      let emails = [];
                      Object.keys(this.state.campaignTestInfo.recentlyContacted).map((email, key) => {
                        emails.push(email)
                      });
                      this.removeRecipients(emails);
                    }}
                  >
                    <span className='icon'><i className='fas fa-trash-can'></i></span>
                    <span className='text'>Remove all</span>
                  </button>
                </div>
                {Object.keys(this.state.campaignTestInfo.recentlyContacted).length == 0
                  ? <div className='flex gap-1 items-center'>No recipients found.</div>
                  : <table className='table-default dense'>
                    <thead>
                      <tr>
                        <th>#</th>
                        <th>{ this.translate('Email') }</th>
                        <th>{ this.translate('When') }</th>
                        <th>{ this.translate('Campaign') }</th>
                        <th></th>
                      </tr>
                    </thead>
                    <tbody>
                      {Object.keys(this.state.campaignTestInfo.recentlyContacted).map((email, key) => {
                        const details = this.state.campaignTestInfo.recentlyContacted[email];
                        return <tr>
                          <td className='text-nowrap'>{key+1}</td>
                          <td className='text-nowrap'>{email}</td>
                          <td className='text-nowrap'>{details.mailSent}</td>
                          <td className='text-nowrap'>{details.campaignName}</td>
                          <td>
                            <button
                              className='btn btn-delete-outline btn-small'
                              onClick={() => {
                                this.removeRecipient(email);
                              }}
                            >
                              <span className='icon'><i className='fas fa-trash-can'></i></span>
                            </button>
                          </td>
                        </tr>;
                      })}
                    </tbody>
                  </table>
                }
              </> : <div className='alert alert-warning'>{ this.translate('Analysing campaign...') }</div>}
            </div>
          </div>
          <div className='card flex-1'>
            <div className='card-header'>{ this.translate('Send test email') }</div>
            <div className='card-body'>
              { this.translate('Test email recipient:') }
              <input
                ref={this.refTestEmailRecipientInput}
                className="ml-2"
                type="text"
                placeholder={ this.translate("Recipient email") }
              />
              <br/>
              { this.translate("Test email variables:") }
              <InputJsonKeyValue uid="test-email-variables"
                onChange={(input: any, value: any) => {
                  input.setState({value: value});
                  this.setState({testEmailVariables: value});
                }}
              ></InputJsonKeyValue>
              <button
                className="btn btn-transparent mt-2"
                onClick={() => {
                  request.post(
                    'campaigns/api/send-test-email',
                    {
                      idCampaign: this.state.record.id,
                      to: this.refTestEmailRecipientInput.current.value,
                      variables: this.state.testEmailVariables,
                    },
                    {},
                    (result: any) => {
                      this.setState({testEmailSendResult: result})
                    }
                  );
                }}
              >
                <span className="icon"><i className="fas fa-envelope"></i></span>
                <span className="text">{this.translate('Send test email')}</span>
              </button>
              {this.state.testEmailSendResult && this.state.testEmailSendResult.status == 'success' ?
                <div className='alert alert-success mt-2'>{ this.translate('Test email was sent to you.') }</div>
              : null}
              {this.state.testEmailSendResult && this.state.testEmailSendResult.status != 'success' ?
                <div className='alert alert-danger mt-2'>
                  { this.translate('Error occured when sending a test email to you.') }
                  <br/>
                  <b>{this.state.testEmailSendResult.message}</b>
                </div>
              : null}
            </div>
          </div>
        </div>;
      break;

      case 'mail.launch':
        let invalidRecipientsCount = 0;
        let unsubscribedRecipientsCount = 0;
        let emailsSent = 0;
        let potentialLeads = [];

        if (this.state.campaignLaunchInfo?.recipients) {
          this.state.campaignLaunchInfo.recipients.map((item, key) => {
            if (item.STATUS?.is_unsubscribed) unsubscribedRecipientsCount++;
            if (item.STATUS?.is_invalid) invalidRecipientsCount++;
            if (item.MAIL?.datetime_sent) emailsSent++;

            let isPotentialLead = false;
            if (item.CLICK_GROUPS) {
              Object.keys(item.CLICK_GROUPS).map((ts, key) => {
                const group = item.CLICK_GROUPS[ts];
                if (
                  group[0] <= 1 // clicks
                  && group[1] == 0 // bot score
                ) {
                  isPotentialLead = true;
                }
              });
            }

            if (isPotentialLead) potentialLeads.push(item.email);
          });
        }

        return <>
          {this.state.campaignLaunchInfo ? <>
            {this.state.campaignLaunchInfo.recentlyContacted
              && this.state.campaignLaunchInfo.recentlyContacted.length > 0 ? <div className='alert alert-warning'>
              <b>{this.translate('Recently contacted')}</b>
              {this.state.campaignLaunchInfo.recentlyContacted.map((item, key) => {
                if (!item.CONTACT) return null;
                return <div key={key}>
                  <code>
                    {item.CONTACT.first_name}&nbsp;{item.CONTACT.last_name}
                    &nbsp;
                    {item.CONTACT.VALUES ? item.CONTACT.VALUES.map((vItem, vKey) => {
                      if (vItem.type == 'email') {
                        return <span key={vKey}>{vItem.value}</span>;
                      } else {
                        return null;
                      }
                    }) : null}
                  </code> {this.translate('in campaign')} <a
                    href={globalThis.hubleto.config.projectUrl + '/campaigns/' + item.CAMPAIGN.id}
                    target='_blank'
                  >{item.CAMPAIGN.name}</a>.
                </div>;
              })}
            </div> : null}
          </> : null}

          {R.id_launched_by ?
            <div className='alert alert-warning'>
              {this.translate(
                'Campaign was already launched by {{ email }} on {{ datetime }}.',
                this.translationContext,
                this.translationContextInner,
                {email: R.LAUNCHED_BY.email, datetime: R.datetime_launched}
              )}</div>
          : null}

          <div className='flex flex-col md:flex-row gap-2 w-full'>
            <div className=''>
              <button
                className="btn btn-add-outline btn-large"
                onClick={() => {
                  request.post(
                    'campaigns/api/launch',
                    { idCampaign: this.state.record.id },
                    {},
                    (result: any) => {
                      this.setState({launchResult: result});
                      if (result.status && result.status == 'success') {
                        updateFormWorkflowByTag(this, 'campaign-launched', () => {
                          this.saveRecord();
                          this.reload();
                        });
                      }
                    }
                  );
                }}
              >
                <span className="icon"><i className="fas fa-paper-plane"></i></span>
                <span className="text">{ this.translate('Launch campaign now!') }</span>
              </button>
              <div className='mt-2 alert alert-info'>
                { this.translate('Emails will be sent only to recipients who did not receive email from this campaign yet.') }
              </div>
              <div className='mt-2 alert alert-info'>
                { this.translate('Unsubscribed and invalid recipients will be ignored.') }
              </div>
              {this.state.campaignLaunchInfo && this.state.campaignLaunchInfo.recipients ? <>
                <div className='card mt-2'>
                  <div className='card-header'>{ this.translate('Statistics') }</div>
                  <div className='card-body flex flex-col gap-1'>
                    <div className='badge'>
                      {this.translate('Recipients')}: {this.state.campaignLaunchInfo.recipients.length}
                    </div>
                    <div className='badge'>
                      {this.translate('Emails sent')}: {emailsSent}
                    </div>
                    <div className='badge badge-warning'>
                      {this.translate('Invalid recipients')}: {invalidRecipientsCount} ({Math.round(invalidRecipientsCount / this.state.campaignLaunchInfo.recipients.length * 100)} %)
                    </div>
                    <div className='badge badge-danger'>
                      {this.translate('Unsubscribed recipients')}: {unsubscribedRecipientsCount} ({Math.round(unsubscribedRecipientsCount / this.state.campaignLaunchInfo.recipients.length * 100)} %)
                    </div>
                  </div>
                </div>
                <div className='card mt-2'>
                  <div className='card-header'>{ this.translate('Potential leads') }</div>
                  <div className='card-body flex flex-wrap gap-1'>
                    {potentialLeads.map((email, key) => {
                      return <div key={key} className='badge'>{email}</div>;
                    })}
                  </div>
                </div>
              </> : null}

              {this.state.launchResult && this.state.launchResult.status == 'success' ?
                <div className='alert alert-success mt-2'>{ this.translate('Campaign was launched.') }</div>
              : null}
              {this.state.launchResult && this.state.launchResult.status != 'success' ?
                <div className='alert alert-danger mt-2'>
                  { this.translate('Error occured when launching the campaign.') }<br/>
                  <b>{this.state.launchResult.message}</b>
                </div>
              : null}
            </div>
            <div className='card grow'>
              <div className='card-header'>{ this.translate('Recipients') }</div>
              <div className='card-body'>
                {this.state.campaignLaunchInfo && this.state.campaignLaunchInfo.recipients ? 
                  <table className='table-default dense'>
                    <thead>
                      <tr>
                        <th rowSpan={2}>#</th>
                        <th rowSpan={2}>{ this.translate('Email') }</th>
                        <th rowSpan={2}>{ this.translate('Status') }</th>
                        <th rowSpan={2}>{ this.translate('Clicks') }</th>
                        <th colSpan={2}>{ this.translate('Bot score') }</th>
                      </tr>
                      <tr>
                        <th>{ this.translate('Total') }</th>
                        <th>{ this.translate('Details') }</th>
                      </tr>
                    </thead>
                    <tbody>
                      {this.state.campaignLaunchInfo.recipients.map((item, key) => {
                        let botScoreTotal = 0;
                        item.CLICKS.map((click, key) => {
                          botScoreTotal += click.bot_score;
                        });

                        let recentlyContacted = this.state.campaignLaunchInfo.recentlyContacted[item.email];

                        return <tr>
                          <td className='text-nowrap'>{key+1}</td>
                          <td className={'text-nowrap' + (item.CLICKS.length > 0 ? ' bg-green-100' : '')}>{item.email}</td>
                          <td className='text-nowrap'>
                            {item.id_mail > 0 ? <>
                              {item.MAIL?.datetime_sent
                                ? <div className='badge badge-success'>{this.translate('Sent')} {item.MAIL?.datetime_sent}</div>
                                : <div className='badge badge-warning'>{this.translate('Scheduled')} {item.MAIL?.datetime_scheduled_to_send}</div>
                              }
                            </> : <div className='badge'>{this.translate('Not scheduled yet')}</div>}
                            {item.STATUS?.is_unsubscribed ? <div className='badge badge-danger'>{this.translate('Unsubscribed')}</div> : null}
                            {item.STATUS?.is_invalid ? <div className='badge badge-warning'>{this.translate('Invalid')}</div> : null}
                            {recentlyContacted ? <div className='badge'>
                              Contacted {recentlyContacted.mailSent} in <i>{recentlyContacted.campaignName}</i>
                            </div> : null}
                          </td>
                          <td>
                            {item.CLICKS.length > 0 ? item.CLICKS.length : null}
                          </td>
                          <td className={'text-nowrap text-red-800'}>{botScoreTotal > 0 ? botScoreTotal : null}</td>
                          <td className='text-nowrap'>
                            {item.CLICK_GROUPS ? Object.keys(item.CLICK_GROUPS).map((ts, key) => {
                              const group = item.CLICK_GROUPS[ts];
                              return <div key={key} className='text-xs'>
                                #{key+1} {moment.unix(parseInt(ts)).format("YYYY-MM-DD HH:mm:ss")} = {group[0]}, {group[1]}
                              </div>;
                            }) : null}
                          </td>
                        </tr>
                      })}
                    </tbody>
                  </table>
                : <div className='alert alert-warning'>{ this.translate('Loading information about recipients and launch status.') }</div>}
              </div>
            </div>
          </div>
        </>;
      break;

      case 'mail.clicks':
        return <TableClicks
          parentForm={this}
          tag="table_campaign_click"
          uid={this.props.uid + "_table_campaign_click"}
          idCampaign={R.id}
        />;
      break;

      case 'mail.timeline':
        return this.renderTimeline([
          {
            data: (thisForm) => thisForm.state.record.ACTIVITIES,
            icon: 'fas fa-calendar',
            color: '#32678fff',
            timestampFormatter: (entry) => entry.date_start,
            valueFormatter: (entry) => entry.subject,
            userNameFormatter: (entry) => entry['_LOOKUP[id_owner]'],
          },
          { 
            data: (thisForm) => thisForm.state.record.WORKFLOW_HISTORY,
            icon: 'fas fa-timeline',
            color: '#8f3248ff',
            timestampFormatter: (entry) => entry.datetime_change,
            valueFormatter: (entry) => entry.WORKFLOW_STEP?.name ?? '---',
            userNameFormatter: (entry) => entry.USER?.nick,
          },
        ]);
      break;

      case 'recipients':
        return <div className='flex gap-2'>
          <div className='flex-3'>
            <TableRecipients
              tag='table_campaign_recipients'
              ref={this.refTableRecipients}
              parentForm={this}
              uid={this.props.uid + "_table_campaign_recipient"}
              idCampaign={R.id}
              view='briefOverview'
              onAfterLoadData={(table: any) => {
                this.setState({ recipients: table.state.data.records });
              }}
            />
          </div>
          <div className='flex-1'>
            <div className='card'>
              <div className='card-header'>{this.translate('Import emails')}</div>
              <div className='card-body'>
                <textarea
                  className='w-full h-80'
                  placeholder={this.translate('One email per line.')}
                  ref={this.refEmails}
                ></textarea>
                <button
                  className='btn btn-add-outline mt-2 w-full'
                  onClick={() => {
                    request.post(
                      'campaigns/api/import-emails',
                      {
                        idCampaign: R.id,
                        emails: this.refEmails.current.value,
                      },
                      {},
                      (data: any) => {
                        this.refTableRecipients.current.reload();
                      }
                    )
                  }}
                >
                  <span className='icon'><i className='fas fa-upload'></i></span>
                  <span className='text'>{this.translate('Import emails')}</span>
                </button>
              </div>
            </div>
          </div>
        </div>;
      break;

      case 'tasks':
        return <TableTasks
          tag={"table_campaign_task"}
          parentForm={this}
          uid={this.props.uid + "_table_campaign_task"}
          junctionTitle='Campaign'
          junctionModel='Hubleto/App/Community/Campaigns/Models/CampaignTask'
          junctionSourceColumn='id_campaign'
          junctionSourceRecordId={R.id}
          junctionDestinationColumn='id_task'
        />;
      break;

      default:
        return super.renderTab(tabUid);
      break;
    }
  }
}

