// imports
import clsx from 'clsx';
import moment from 'moment';
import { Float } from '@headlessui-float/react';
import { Listbox } from '@headlessui/react';
import React, { useCallback, useEffect, useState } from 'react';
import { IconBranch, IconSearch, IconEdit, IconPlus } from '@chirper/react/src/icons';

// locals
import Input from '../Input';
import Button from '../Button';
import useTeam from '../../hooks/useTeam';
import ApiSignal from '../../signals/Api';
import ButtonIcon from '../Button/Icon';
import { useSignal } from '../../signal';
import { useCommits } from '../../data/useCommit';
import { useBranches } from '../../data/useBranch';
import { DropdownItem } from '../Dropdown';
import { branch as BranchSignal } from './Modal';

/**
 * branch dropdown
 *
 * @param param0 
 * @returns 
 */
const BranchDropdown = ({
  value = null,
  workflow = null,
  onChange = (b) => {},
  commit = null,
  onCommit = (c) => {},
}) => {
  // signals
  const [sApi] = useSignal(ApiSignal);
  const [,setBranch] = useSignal(BranchSignal);
  
  // team
  const team = useTeam();

  // items
  const { branches, handleItem } = useBranches({
    team     : team?.id,
    workflow : workflow?.id,
  }, {
    disable : !workflow?.id || !team?.id,
  });
  const { commits, handleItem : handleCommit } = useCommits({
    team     : team?.id,
    branch   : value?.id || workflow?.branch?.id || workflow?.branch,
    workflow : workflow?.id,
  }, {
    disable : !workflow?.id || !team?.id || !(value?.id || workflow?.branch?.id || workflow?.branch),
  });

  // current branch
  const currentBranch = branches.find(branch => branch.id === (value ? value.id : (workflow?.branch?.id || workflow?.branch)));

  // shorten commit to len characters
  const shortenId = useCallback((id, len = 7) => id.slice(0, len) + '...', []);

  const [open, setOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [activeTab, setActiveTab] = useState('branches');

  const filteredBranches = branches.filter(branch => 
    branch.name.toLowerCase().includes(searchQuery.toLowerCase())
  );

  // handle create branch
  const handleCreate = async (opts = {}) => {
    // create branch
    const { branch } = await sApi.Branch.create({
      ...opts,
      team     : team?.id,
      workflow : workflow?.id,
    });

    // add to handle item
    handleItem(branch);

    // set current branch
    onChange(branch);
  };

  // handle edit branch
  const handleUpdate = (e, branch) => {
    e.stopPropagation();
    setBranch(branch);
  };

  // use effect
  useEffect(() => {
    console.log('COMMIT UPDATED!');
    // check commit
    if (!commit?.id) return;
    if (commit?.branch !== value?.id) return;
    
    // handle commit
    handleCommit(commit);
  }, [commit]);
  useEffect(() => {
    // check value
    if (!value?.id) return;
    if (!commits.length) return;

    // get most recent commit, with this branch
    const found = commits.find(c => c.branch === value.id);

    // set commit
    if (found) onCommit(found);
  }, [value?.id, commits]);

  // return jsx
  return (
    <div className="flex gap-2 items-center">
      <Listbox
        
      >
        <Float
          as="div"
          floatingAs={React.Fragment}
          placement="bottom-end"
          offset={4}
          flip
          shift
          portal
          enter="transition duration-200 ease-out"
          enterFrom="scale-95 opacity-0"
          enterTo="scale-100 opacity-100"
          leave="transition duration-150 ease-in"
          leaveFrom="scale-100 opacity-100"
          leaveTo="scale-95 opacity-0"
          onShow={() => setOpen(true)}
          onHide={() => setOpen(false)}
        >
          <Listbox.Button as="div">
            <Button
              color={open ? 'primary' : 'transparent'}
              className="flex items-center"
            >
              <IconBranch className="mr-2 w-4 h-4" />
              <span>{currentBranch?.name}</span>
      
              {commit?.id && (
                <span className={clsx(
                  'px-2 py-1 ml-2 text-xs font-medium rounded-full border border-gray-400',
                  open && '!border-white'
                )}>
                  {`#${shortenId(commit?.id)}`}
                </span>
              )}
            </Button>
          </Listbox.Button>

          <Listbox.Options className="z-50 mt-1 w-80">
            <div className="overflow-hidden w-full card focus-within:!ring-gray-200/20 dark:focus-within:!ring-gray-400">
              <div className="p-3">
                <Input
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  placeholder="Search or create a branch"
                  startAdornment={<IconSearch className="mr-3 w-4 h-4" />}
                />
              </div>

              <div className="border-t border-gray-700">
                <div className="flex px-1 border-b border-gray-700">
                  <button
                    className={`flex-1 px-4 py-2 text-sm font-medium border-b-2 ${
                      activeTab === 'branches'
                        ? 'text-white border-primary-500'
                        : 'text-gray-400 hover:text-gray-200 border-transparent'
                    }`}
                    onClick={() => setActiveTab('branches')}
                  >
                    Branches
                  </button>
                  <button
                    className={`flex-1 px-4 py-2 text-sm font-medium border-b-2 ${
                      activeTab === 'history'
                        ? 'text-white border-primary-500'
                        : 'text-gray-400 hover:text-gray-200 border-transparent'
                    }`}
                    onClick={() => setActiveTab('history')}
                  >
                    History
                  </button>
                </div>

                <div className="overflow-y-auto max-h-80">
                  {activeTab === 'branches' ? (
                    <div className="py-1">
                      {filteredBranches.map((branch) => (
                        <DropdownItem
                          key={branch.id}
                          selected={value?.id === branch.id}
                          onClick={() => {
                            onChange?.(branch);
                            setOpen(false);
                          }}
                          className={clsx(
                            '!py-2 group',
                            value?.id === branch.id && 'bg-primary-500/50',
                          )}
                          
                        >
                          <div className="flex flex-1 items-center">
                            {branch.name}
                            {(branch.id === (workflow?.branch?.id || workflow?.branch)) && (
                              <span className="ml-auto text-xs">default</span>
                            )}
                          </div> 
                          <ButtonIcon
                            color="primary"
                            onClick={(e) => handleUpdate(e, branch)}
                            className="ml-2 opacity-0 group-hover:opacity-100"
                          >
                            <IconEdit className="w-4 h-4" />
                          </ButtonIcon>
                        </DropdownItem>
                      ))}

                      {searchQuery.length > 0 && filteredBranches.length === 0 && (
                        <DropdownItem
                          icon={IconPlus}
                          onClick={() => {
                            handleCreate({
                              name: searchQuery,
                            });
                          }}
                        >
                          Create "{searchQuery}" branch
                        </DropdownItem>
                      )}
                    </div>
                  ) : (
                    <div className="py-1">
                      {commits.map((commitItem) => (
                        <DropdownItem
                          key={commitItem.id}
                          selected={commit?.id === commitItem.id}
                          onClick={() => {
                            onCommit(commitItem);
                            setOpen(false);
                          }}
                          className={clsx(
                            'group',
                            commit?.id === commitItem.id && 'bg-primary-500/50',
                          )}
                        >
                          <div className="flex flex-col flex-1 min-w-0">
                            <span className="font-medium truncate group-hover:text-white">
                              {commitItem.message}
                            </span>
                            <div className="flex items-center mt-1 text-xs">
                              <span className="font-mono">#{shortenId(commitItem.id)}</span>
                              <span className="mx-2">
                                &middot;
                              </span>
                              <span>
                                {moment(commitItem.createdAt).fromNow()}
                              </span>
                            </div>
                          </div>
                        </DropdownItem>
                      ))}
                    </div>
                  )}
                </div>
              </div>
            </div>
          </Listbox.Options>
        </Float>
      </Listbox>
    </div>
  );
};

export default BranchDropdown;