
// imports
import Tabs from '@chirper/react/src/components/Tabs';
import React, { useState } from 'react';

// locals
import Input from '../Input';
import Button from '../Button';
import Overlay from '../Overlay';
import Confirm from '../Confirm';
import ApiSignal from '../../signals/Api';
import NodesSignal from '../../signals/Nodes';
import { addSnack } from '../../signals/Snacks';
import ComponentSecretSelect from '../Secret/Select';
import { current as TeamSignal } from '../../signals/Teams';
import Signal, { useComputed, useSignal } from '../../signal';

// open
export const tab     = new Signal.State('invite');
export const member  = new Signal.State(null);
export const remove  = new Signal.State(null);
export const removed = new Signal.State([]);
export const created = new Signal.State([]);

/**
 * component team modal
 *
 * @param props 
 */
const ComponentTeamModal = (props = {}) => {
  // signals
  const [sApi] = useSignal(ApiSignal);
  const [sTeam] = useSignal(TeamSignal);

  // sremove
  const [sTab, setTab]         = useSignal(tab);
  const [sRemove, setRemove]   = useSignal(remove);
  const [sMember, setMember]   = useSignal(member);
  const [sRemoved, setRemoved] = useSignal(removed);
  const [sCreated, setCreated] = useSignal(created);
  
  // use state
  const [saving, setSaving] = useState(false);
  const [removing, setRemoving] = useState(false);

  // get provider nodes
  const [providers] = useComputed(() => {
    // return nodes
    return Object.values(NodesSignal.get() || {}).filter((n) => (n.outputs || []).find((o) => o.type?.[0]?.id === 'provider.llm'));
  });

  // on remove
  const onRemove = async () => {
    // check removing
    if (removing) return;

    // set removing
    setRemoving(true);

    // try/catch
    try {
      // remove member
      await sApi.Team.Member.remove(sRemove.id);

      // add to removed
      setRemoved([...sRemoved, sRemove?.id]);

      // done
      setRemove(null);
      setMember(null);

      // add success
      addSnack({
        id       : 'team.member.removed',
        message  : sApi.translate('team:snack.removed', 'Team member removed'),
        severity : 'success',
      });
    } catch (e) {
      // log
      console.error(e);
    } finally {
      // set removing
      setRemoving(false);
    }
  };

  // on save
  const onSave = async () => {
    // save team
    if (saving) return;

    // set saving
    setSaving(true);

    // try/catch
    try {
      // save team
      const result = await sApi.Team.Member[(sMember?.member || sMember?.id) ? 'update' : 'create']({
        ...sMember, 
        id       : (sMember?.member || sMember?.id),
        team     : sTeam.id,
        role     : sTab === 'agent' ? 'agent' : 'member',
        provider : (sMember?.provider || '668218c2604cd8a0'),
      });

      // set team value
      setMember(null);
      setCreated([...sCreated, result?.member]);

      // on change1
      if (props.onChange) props.onChange(sMember);
    } catch (e) {
      // log
      console.error(e);
    } finally {
      // set saving
      setSaving(false);
    }
  };

  // return jsx
  return (
    <>
      <Overlay
        open={!!sMember}
        title={sMember?.name || sApi.translate('team:dialog.title', 'Create Team Member')}
        onClose={() => setMember(null)}
        subtitle={sApi.translate('team:dialog.subtitle', 'Create a new team member')}
      >
        {!sMember?.id && (
          <Tabs
            tab={sTab || 'invite'}
            onTab={setTab}
            
            tabs={[
              {
                id   : 'invite',
                name : sApi.translate('team:tab.invite', 'Invite Human'),
              },
              {
                id   : 'agent',
                name : sApi.translate('team:tab.agent', 'Invite Agent'),
              },
            ]}
          />
        )}
        
        <Input
          name="name"
          type="text"
          label={sApi.translate('team:form.name.label', 'Name')}
          value={sMember?.name || sMember?.user?.name || ''}
          onChange={(e) => setMember({ ...sMember, name : e.target.value })}
          placeholder={sApi.translate('team:form.name.placeholder', 'Enter a name')}
        />
        {(sMember?.id ? !sMember.agent : ((sTab || 'invite') === 'invite')) && (
          <Input
            name="email"
            type="email"
            label={sApi.translate('team:form.email.label', 'Email')}
            value={sMember?.email || sMember?.user?.email || ''}
            onChange={(e) => setMember({ ...sMember, email : e.target.value })}
            placeholder={sApi.translate('team:form.email.placeholder', 'Enter an email')}
          />
        )}
        {(sMember?.id ? sMember.agent : (sTab === 'agent')) && (
          <>
            <Input
              name="system"
              type="textarea"
              label={sApi.translate('team:form.system.label', 'System Prompt')}
              value={sMember?.agent?.system || ''}
              minRows={5}
              maxRows={10}
              onChange={(e) => setMember({ ...sMember, agent : {
                ...sMember.agent,
                system : e.target.value,
              } })}
              placeholder={sApi.translate('team:form.system.placeholder', 'Enter AI System Prompt')}
            />
            <Input
              name="provider" 
              type="select"
              label={sApi.translate('team:form.provider.label', 'LLM Provider')}
              value={sMember?.agent?.provider || '668218c2604cd8a0'}
              onChange={(e) => setMember({ ...sMember, agent : {
                ...sMember.agent,
                provider : e.target.value,
              } })}
              placeholder={sApi.translate('team:form.provider.placeholder', 'Enter LLM Provider')}
            >
              {providers.map((provider) => (
                <option key={provider.id} value={provider.id}>
                  {provider.name}
                </option>
              ))}
            </Input>
            <Input
              name="model"
              label={sApi.translate('team:form.model.label', 'LLM Model')}
              value={sMember?.agent?.model || ''}
              onChange={(e) => setMember({ ...sMember, agent : {
                ...sMember.agent,
                model : e.target.value,
              } })}
              placeholder={sApi.translate('team:form.model.placeholder', 'Enter LLM model')}
            />
            <ComponentSecretSelect
              value={sMember?.agent?.secret}
              label={sApi.translate('team:form.secret.label', 'LLM Secret')}
              onChange={(val) => setMember({ ...sMember, agent : {
                ...sMember.agent,
                secret : val,
              } })}
              placeholder={sApi.translate('team:form.secret.placeholder', 'Enter LLM secret')}
            />
          </> 
        )}
        
        <div className="pt-4 sm:pt-6 sm:flex sm:flex-row-reverse">
          <Button
            color="primary"
            onClick={onSave}
          >
            {saving ? sApi.translate('team:button.loading', 'Loading...') : sApi.translate('team:button.submit', 'Submit')}
          </Button>
          <Button
            color="transparent"
            onClick={() => setMember(null)}
          >
            {sApi.translate('team:button.cancel', 'Cancel')}
          </Button>
          {!!sMember?.id && (
            <Button
              color="error"
              onClick={() => [setRemove(sMember), setMember(null)]}
              className="mr-auto"
            >
              {sApi.translate('team:button.remove', 'Remove')}
            </Button>
          )}
        </div>
      </Overlay>
      <Confirm
        open={!!sRemove}
        title={sApi.translate('team:dialog.remove.title', 'Remove Team Member')}
        loading={removing}
        onClose={() => setRemove(null)}
        subtitle={sApi.translate('team:dialog.remove.message', 'Are you sure you want to remove this team member?')}
        onConfirm={onRemove}
      />
    </>
  );
};

/**
 * export component team modal
 */
export default ComponentTeamModal;