import { useResourceFileStore } from '@kevisual/resources/pages/store/resource-file';
import { FormControlLabel, Box, TextField, Button, IconButton, ButtonGroup, Tooltip, Select, MenuItem, Typography, FormGroup } from '@mui/material';
import { Info, Plus, Save, Share, Shuffle, Trash } from 'lucide-react';
import { useState, useEffect, useMemo } from 'react';
import { toast } from 'react-toastify';
import { create } from 'zustand';
import { uniq } from 'lodash-es';
import { DatePicker } from './DatePicker';
import { SelectPicker } from './SelectPicker';
import dayjs from 'dayjs';
import { DialogKey } from './DialogKey';

export const setShareKeysOperate = (value: 'public' | 'protected' | 'private') => {
  const keys = ['password', 'usernames', 'expiration-time'];
  const deleteKeys = keys.map((item) => {
    return {
      key: item,
      operate: 'delete',
    };
  });
  if (value === 'protected') {
    return deleteKeys.map((item) => {
      return {
        ...item,
        operate: 'add',
      };
    });
  }
  return deleteKeys;
};
export const keysTips = [
  {
    key: 'share',
    tips: `共享设置
    1. 设置公共可以直接访问
    2. 设置受保护需要登录后访问
    3. 设置私有只有自己可以访问。\n
    受保护可以设置密码，设置访问的用户名。切换共享状态后，需要重新设置密码和用户名。`,
  },
  {
    key: 'content-type',
    tips: `内容类型，设置文件的内容类型。默认不要修改。`,
  },
  {
    key: 'app-source',
    tips: `应用来源，上传方式。默认不要修改。`,
  },
  {
    key: 'cache-control',
    tips: `缓存控制，设置文件的缓存控制。默认不要修改。`,
  },
  {
    key: 'password',
    tips: `密码，设置文件的密码。不设置默认是所有人都可以访问。`,
  },
  {
    key: 'usernames',
    tips: `用户名，设置文件的用户名。不设置默认是所有人都可以访问。`,
    parse: (value: string) => {
      if (!value) {
        return [];
      }
      return value.split(',');
    },
    stringify: (value: string[]) => {
      if (!value) {
        return '';
      }
      return value.join(',');
    },
  },
  {
    key: 'expiration-time',
    tips: `过期时间，设置文件的过期时间。不设置默认是永久。`,
    parse: (value: Date) => {
      if (!value) {
        return null;
      }
      return dayjs(value);
    },
    stringify: (value?: dayjs.Dayjs) => {
      if (!value) {
        return '';
      }
      return value.toISOString();
    },
  },
];
export class KeyParse {
  static parse(metadata: Record<string, any>) {
    const keys = Object.keys(metadata);
    const newMetadata = {};
    keys.forEach((key) => {
      const tip = keysTips.find((item) => item.key === key);
      if (tip && tip.parse) {
        newMetadata[key] = tip.parse(metadata[key]);
      } else {
        newMetadata[key] = metadata[key];
      }
    });
    return newMetadata;
  }
  static stringify(metadata: Record<string, any>) {
    const keys = Object.keys(metadata);
    const newMetadata = {};
    keys.forEach((key) => {
      const tip = keysTips.find((item) => item.key === key);
      if (tip && tip.stringify) {
        newMetadata[key] = tip.stringify(metadata[key]);
      } else {
        newMetadata[key] = metadata[key];
      }
    });
    return newMetadata;
  }
}
export const useMetaOperate = ({
  onSave,
  metaStore,
  handleFormDataChange,
}: {
  onSave: () => void;
  metaStore: MetaStore;
  handleFormDataChange: (key: string, value: string | Date | null | string[]) => void;
}) => {
  const { keys, setKeys, openPropertyModal, setOpenPropertyModal } = metaStore;
  const hasShare = keys.includes('share');
  const hasPassword = keys.includes('password');
  const addMeta = (key: string) => {
    setKeys(uniq([...keys, key]));
  };
  const defaultBtnList = [
    {
      icon: <Save />,
      key: 'save',
      tooltip: '保存元数据, 修改后需要手动保存',
      onClick: () => onSave(),
    },
    {
      icon: <Plus />,
      key: 'add',
      tooltip: '添加元数据',
      onClick: () => setOpenPropertyModal(true),
    },
  ];
  if (!hasShare) {
    defaultBtnList.push({
      icon: <Share />,
      key: 'share',
      tooltip: '开启共享',
      onClick: () => addMeta('share'),
    });
  }
  if (hasShare && hasPassword) {
    defaultBtnList.push({
      icon: <Shuffle />,
      key: 'password',
      tooltip: '随机生成密码',
      onClick: () => {
        const password = Math.random().toString(36).substring(2, 8);
        handleFormDataChange('password', password);
      },
    });
  }
  return defaultBtnList;
};
type MetaStore = {
  keys: string[];
  setKeys: (keys: string[]) => void;
  openPropertyModal: boolean;
  setOpenPropertyModal: (openPropertyModal: boolean) => void;
};
export const useMetaStore = create<MetaStore>((set) => ({
  keys: [],
  setKeys: (keys) => set({ keys }),
  openPropertyModal: false,
  setOpenPropertyModal: (openPropertyModal) => set({ openPropertyModal }),
}));
export const MetaForm = () => {
  const { resource, updateMeta } = useResourceFileStore();
  const [formData, setFormData] = useState<any>({});
  const metaStore = useMetaStore();
  const { keys, setKeys } = metaStore;
  useEffect(() => {
    // setFormData(resource?.metaData || {});
    setFormData(KeyParse.parse(resource?.metaData || {}));
  }, [resource]);
  useEffect(() => {
    setKeys(Object.keys(resource?.metaData || {}));
  }, [resource]);
  if (!keys.length) {
    return <div className='text-center text-gray-500'>没有元数据</div>;
  }

  const handleFormDataChange = (key: string, value: string | Date | null | string[]) => {
    // setFormData({ ...formData, [key]: value });
    const _formData = { ...formData };
    if (key === 'share') {
      const shareKeysOperate = setShareKeysOperate(value as 'public' | 'protected' | 'private');
      shareKeysOperate.forEach((item) => {
        if (item.operate === 'add') {
          _formData[item.key] = '';
        } else if (item.operate === 'delete') {
          delete _formData[item.key];
        }
      });
      _formData.share = value;
      setFormData(_formData);
      const newKeys = keys
        .map((item) => {
          const operate = shareKeysOperate.find((item2) => item2.key === item);
          if (operate && operate.operate === 'delete') {
            return null;
          }
          return item;
        })
        .filter((item) => item !== null);
      const addKeys = shareKeysOperate.filter((item) => item.operate === 'add').map((item) => item.key);
      const _newKeys = uniq([...newKeys, ...addKeys]);
      setKeys(_newKeys);
      console.log(_newKeys);
      return;
    } else {
      _formData[key] = value;
    }
    setFormData(_formData);
  };
  const deleteMeta = (key: string) => {
    setKeys(keys.filter((item) => item !== key));
    delete formData[key];
    setFormData({ ...formData });
  };
  const onSave = () => {
    const newMetadata = KeyParse.stringify(formData);
    updateMeta(newMetadata);
  };
  const addMetaKey = (key: string) => {
    if (keys.includes(key)) {
      toast.error('元数据key已存在');
      return;
    }
    formData[key] = '';
    setKeys([...keys, key]);
    setFormData({ ...formData });
  };
  const btnList = useMetaOperate({ onSave, metaStore, handleFormDataChange });

  return (
    <div className='relative w-full h-full'>
      <Box className='sticky top-0 z-10  pointer-events-none'>
        <div className='flex justify-end mr-20'>
          <div className=' pointer-events-auto'>
            <ButtonGroup className='bg-white' variant='contained' sx={{ color: 'white' }}>
              {btnList.map((item) => {
                const icon = (
                  <IconButton color='secondary' onClick={item.onClick}>
                    {item.icon}
                  </IconButton>
                );
                if (item.tooltip) {
                  return (
                    <Tooltip key={item.key} title={item.tooltip} placement='top' arrow>
                      {icon}
                    </Tooltip>
                  );
                }
                return <>{icon}</>;
              })}
            </ButtonGroup>
          </div>
        </div>
      </Box>
      <FormGroup>
        {keys.map((key) => {
          let control: React.ReactNode | null = null;
          if (key === 'share') {
            control = <KeyShareSelect name={key} value={formData[key] || ''} onChange={(value) => handleFormDataChange(key, value)} />;
          } else if (key === 'expiration-time') {
            control = <DatePicker value={formData[key]} onChange={(date) => handleFormDataChange(key, date)} />;
          } else if (key === 'usernames') {
            control = <SelectPicker value={formData[key] || []} onChange={(value) => handleFormDataChange(key, value)} />;
          } else {
            control = <KeyTextField name={key} value={formData[key] || ''} onChange={(value) => handleFormDataChange(key, value)} />;
          }
          const Label = () => {
            const tip = keysTips.find((item) => item.key === key);
            return (
              <div className='flex justify-between items-center gap-2'>
                <div className='flex items-center gap-2'>
                  <Typography variant='caption' color='primary'>
                    {key}
                  </Typography>
                  {tip && (
                    <Tooltip title={tip?.tips} placement='top' arrow>
                      <Info size={12} />
                    </Tooltip>
                  )}
                </div>
                <IconButton color='error' onClick={() => deleteMeta(key)}>
                  <Trash />
                </IconButton>
              </div>
            );
          };
          return (
            <div key={key} className='flex flex-col gap-2'>
              <FormControlLabel
                key={key}
                label={<Label />}
                labelPlacement='top'
                control={control}
                sx={{
                  alignItems: 'flex-start',
                  '& .MuiFormControlLabel-label': {
                    textAlign: 'left',
                    width: '100%',
                  },
                }}
              />
            </div>
          );
        })}
      </FormGroup>
      <DialogKey onAdd={addMetaKey} />
    </div>
  );
};

const KeyTextField = ({ name, value, onChange }: { name: string; value: string; onChange?: (value: string) => void }) => {
  return (
    <TextField
      variant='outlined'
      size='small'
      name={name}
      defaultValue={value}
      // value={formData[key] || ''}
      onChange={(e) => onChange?.(e.target.value)}
      sx={{
        width: '100%',
        marginBottom: '16px',
      }}
    />
  );
};
const KeyShareSelect = ({ name, value, onChange }: { name: string; value: string; onChange?: (value: string) => void }) => {
  return (
    <Select
      variant='outlined'
      size='small'
      name={name}
      value={value}
      onChange={(e) => onChange?.(e.target.value)}
      sx={{
        width: '100%',
        marginBottom: '16px',
      }}>
      <MenuItem value='public' title='公开'>
        公开
      </MenuItem>
      <MenuItem value='protected' title='受保护'>
        受保护
      </MenuItem>
      <MenuItem value='private' title='私有'>
        私有
      </MenuItem>
    </Select>
  );
};
