/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////

/* The complete styling file for Material-UI components used
 * This will become the main theme file for pgAdmin. All the
 * custom themes info will come here.
 */

import React, { useMemo } from 'react';
import { createMuiTheme, ThemeProvider, makeStyles } from '@material-ui/core/styles';
import CustomPropTypes from '../custom_prop_types';

import getStandardTheme from './standard';
import getDarkTheme from './dark';
import getHightContrastTheme from './high_contrast';

/* Common settings across all themes */
let basicSettings = createMuiTheme();
basicSettings = createMuiTheme(basicSettings, {
  typography: {
    fontSize: 14,
    htmlFontSize: 14,
  },
  shape: {
    borderRadius: 4,
  },
  palette: {
    action: {
      disabledOpacity: 0.32,
    }
  },
  overrides: {
    MuiTabs: {
      root: {
        minHeight: 0,
      }
    },
    PrivateTabIndicator: {
      root: {
        height: '3px',
        transition: basicSettings.transitions.create(['all'], {duration: '150ms'}),
      }
    },
    MuiTab: {
      root: {
        textTransform: 'none',
        minHeight: 0,
        padding: '3px 10px',
        [basicSettings.breakpoints.up('xs')]: {
          minWidth: 0,
        },
        [basicSettings.breakpoints.up('sm')]: {
          minWidth: 0,
        },
        [basicSettings.breakpoints.up('md')]: {
          minWidth: 0,
        },
        [basicSettings.breakpoints.up('lg')]: {
          minWidth: 0,
        },
      },
      textColorInherit: {
        textTransform: 'none',
        opacity: 1,
      }
    },
    MuiButton: {
      root: {
        textTransform: 'none',
        padding: basicSettings.spacing(0.5, 1.5),
        '&.Mui-disabled': {
          opacity: 0.60,
        },
        '&.MuiButton-sizeSmall, &.MuiButton-outlinedSizeSmall, &.MuiButton-containedSizeSmall': {
          height: '28px',
          fontSize: '0.875rem',
          '& .MuiSvgIcon-root': {
            height: '0.8em',
          }
        },
      },
      contained: {
        boxShadow: 'none',
        '&:hover': {
          boxShadow: 'none',
        }
      },
      outlined: {
        padding: basicSettings.spacing(0.375, 1),
      },
      startIcon: {
        marginRight: basicSettings.spacing(0.5),
      },
    },
    MuiOutlinedInput: {
      multiline: {
        padding: '0px',
      },
      input: {
        padding: basicSettings.spacing(0.75, 1.5),
        borderRadius: 'inherit',
      },
      inputMultiline: {
        padding: basicSettings.spacing(0.75, 1.5),
        resize: 'vertical',
      },
      adornedEnd: {
        paddingRight: basicSettings.spacing(0.75),
      }
    },
    MuiAccordion: {
      root: {
        boxShadow: 'none',
      }
    },
    MuiAccordionSummary: {
      root: {
        minHeight: 0,
        '&.Mui-expanded': {
          minHeight: 0,
        },
        padding: basicSettings.spacing(0, 1),
        fontWeight: basicSettings.typography.fontWeightBold,
      },
      content: {
        margin: basicSettings.spacing(1),
        '&.Mui-expanded': {
          margin: basicSettings.spacing(1),
        }
      },
      expandIcon: {
        order: -1,
      }
    },
    MuiAccordionDetails: {
      root: {
        padding: basicSettings.spacing(1),
      }
    },
    MuiFormControlLabel: {
      root: {
        marginBottom: 0,
        marginLeft: 0,
        marginRight: 0,
      }
    },
    MuiFormHelperText: {
      root: {
        fontSize: '1em',
      },
      contained: {
        marginLeft: 0,
        marginRight: 0,
      }
    },
    MuiTypography: {
      body1: {
        fontSize: '1em',
      }
    },
    MuiDialog: {
      paper: {
        margin: 0,
      }
    },
    MuiTooltip: {
      popper: {
        top: 0,
        zIndex: 9999,
      }
    },
    MuiMenu: {
      list: {
        padding: '0',
      }
    },
    MuiMenuItem: {
      root: {
        fontSize: 14,
      }
    },
    MuiSelect: {
      selectMenu: {
        minHeight: 'unset',
      },
      select:{
        '&:focus':{
          backgroundColor: 'unset',
        }
      }
    }
  },
  transitions: {
    create: () => 'none',
  },
  zIndex: {
    modal: 3001,
  },
  props: {
    MuiTextField: {
      variant: 'outlined',
    },
    MuiButton: {
      disableTouchRipple: true,
    },
    MuiIconButton: {
      size: 'small',
      disableTouchRipple: true,
    },
    MuiAccordion: {
      defaultExpanded: true,
    },
    MuiTab: {
      textColor: 'inherit',
    },
    MuiCheckbox: {
      disableTouchRipple: true,
    },
    MuiDialogTitle: {
      disableTypography: true,
    },
    MuiCardHeader: {
      disableTypography: true,
    },
    MuiListItem: {
      disableGutters: true,
    },
  },
});

/* Get the final theme after merging base theme with selected theme */
function getFinalTheme(baseTheme) {
  let mixins = {
    panelBorder: {
      border: '1px solid '+baseTheme.otherVars.borderColor,
      all: {
        border: '1px solid '+baseTheme.otherVars.borderColor,
      },
      top: {
        borderTop: '1px solid '+baseTheme.otherVars.borderColor,
      },
      bottom: {
        borderBottom: '1px solid '+baseTheme.otherVars.borderColor,
      },
      right: {
        borderRight: '1px solid '+baseTheme.otherVars.borderColor,
      }
    },
    nodeIcon: {
      backgroundPosition: 'center',
      padding: baseTheme.spacing(0, 1.5),
    },
    tabPanel: {
      height: '100%',
      padding: baseTheme.spacing(1),
      overflow: 'auto',
      backgroundColor: baseTheme.palette.grey[400],
      position: 'relative',
    },
    fontSourceCode: {
      fontFamily: '"Source Code Pro", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
    }
  };

  return createMuiTheme({
    mixins: mixins,
    overrides: {
      MuiOutlinedInput:  {
        root: {
          '&.Mui-disabled .MuiOutlinedInput-notchedOutline': {
            borderColor: baseTheme.otherVars.inputBorderColor,
          },
        },
        notchedOutline: {
          borderColor: baseTheme.otherVars.inputBorderColor,
        }
      },
      MuiFormControlLabel: {
        label: {
          '&.Mui-disabled': {
            color: baseTheme.palette.text.muted
          }
        }
      },
      MuiTabs: {
        root: {
          backgroundColor: baseTheme.otherVars.headerBg,
          ...mixins.panelBorder.bottom
        },
        indicator: {
          backgroundColor: baseTheme.otherVars.activeColor,
        }
      },
      MuiFormLabel: {
        root: {
          color: baseTheme.palette.text.primary,
          fontSize: baseTheme.typography.fontSize,
        },
        asterisk: {
          color: baseTheme.palette.error.main,
        }
      },
      MuiInputBase: {
        root: {
          backgroundColor: baseTheme.palette.background.default,
          textOverflow: 'ellipsis',
          '&.Mui-disabled': {
            backgroundColor: baseTheme.otherVars.inputDisabledBg,
          },
        },
        inputMultiline: {
          fontSize: baseTheme.typography.fontSize,
          height: 'unset',
          backgroundColor: baseTheme.palette.background.default,
          '&[readonly], &.Mui-disabled': {
            color: baseTheme.palette.text.muted,
            backgroundColor: baseTheme.otherVars.inputDisabledBg,
          },
        },
        input: {
          fontSize: baseTheme.typography.fontSize,
          height: 'unset',
          backgroundColor: baseTheme.palette.background.default,
          '&[readonly], &.Mui-disabled': {
            color: baseTheme.palette.text.muted,
            backgroundColor: baseTheme.otherVars.inputDisabledBg,
          },
          '&:focus': {
            outline: '0 !important',
          }
        },
      },
      MuiIconButton: {
        root: {
          color: baseTheme.palette.text.primary,
          '&$disabled': {
            color: 'abc',
          }
        }
      },
      MuiAccordion: {
        root: {
          ...mixins.panelBorder,
        }
      },
      MuiAccordionSummary: {
        root: {
          ...mixins.panelBorder.bottom,
          backgroundColor: baseTheme.otherVars.headerBg,
        }
      },
      MuiToggleButtonGroup: {
        groupedHorizontal : {
          '&:not(:first-child)': {
            borderLeft: 'abc'
          }
        }
      },
      MuiSwitch: {
        root: {
          width: 54,
          height: 28,
          padding: '7px 12px',
        },
        colorPrimary: {
          '&$disabled': {
            color: 'abc',
            '& + .MuiSwitch-track': {
              backgroundColor: 'abc',
            }
          }
        },
        switchBase: {
          padding: baseTheme.spacing(0.5),
          '&$disabled': {
            color: 'abc',
            '& + .MuiSwitch-track': {
              opacity: baseTheme.palette.action.disabledOpacity,
            }
          },
          '&.Mui-checked': {
            color: baseTheme.palette.success.main,
            transform: 'translateX(24px)',
            '& .MuiSwitch-thumb': {
              border: 0
            }
          },
          '&.Mui-checked + .MuiSwitch-track': {
            backgroundColor: baseTheme.palette.success.light,
          },
        },
        thumb: {
          border: '1px solid ' + baseTheme.otherVars.inputBorderColor
        },
        track: {
          backgroundColor: baseTheme.otherVars.toggleBtnBg
        }
      },
      MuiCheckbox: {
        root: {
          padding: '0px',
          color: baseTheme.otherVars.inputBorderColor,
        },

        colorPrimary: {
          '&.Mui-disabled': {
            color: baseTheme.palette.checkbox.disabled
          }
        }
      },
      MuiToggleButton: {
        root: {
          padding: 'abc',
          paddingRight: baseTheme.spacing(2.5),
          paddingLeft: baseTheme.spacing(0.5),
          color: 'abc',
          '&:hover':{
            backgroundColor: 'abc',
          },
          '&$selected': {
            color: 'abc',
            backgroundColor: 'abc',
            '&:hover':{
              backgroundColor: 'abc',
            }
          }
        },

        label: {
          textTransform: 'initial',
        }
      },
      MuiFormHelperText: {
        root: {
          color: baseTheme.palette.text.muted,
        },
      },
      MuiDialogContent: {
        root: {
          padding: 0,
          userSelect: 'text',
        }
      },
      MuiDialogTitle: {
        root: {
          fontWeight: 'bold',
          padding: '5px 10px',
          cursor: 'move',
          display: 'flex',
          alignItems: 'center',
          ...mixins.panelBorder.bottom,
        }
      },
      MuiCardHeader: {
        root: {
          padding: '4px 8px',
          ...mixins.panelBorder.bottom,
        }
      },
      MuiCardContent: {
        root: {
          padding: 0,
          '&:last-child': {
            paddingBottom: 0,
          }
        }
      },
      MuiListItem: {
        root: {
          color: baseTheme.palette.text.primary,
          backgroundColor: baseTheme.palette.background.default,
          flexDirection: 'column',
          alignItems: 'initial',
          padding: '0px 4px',
          paddingTop: '0px',
          paddingBottom: '0px',
          ...mixins.panelBorder.top,
          ...mixins.panelBorder.bottom,
          borderTopColor: 'transparent',
          cursor: 'pointer',
          '&$selected': {
            backgroundColor: baseTheme.palette.primary.light,
            borderColor: baseTheme.palette.primary.main,
            '&:hover': {
              backgroundColor: baseTheme.palette.primary.light,
            }
          },
        }
      }
    }
  }, baseTheme);
}

/* Theme wrapper used by DOM containers to apply theme */
/* In future, this will be moved to App container */
export default function Theme(props) {
  const theme = useMemo(()=>{
    /* We'll remove this in future, we can get the value from preferences directly */
    let themeName = document.querySelector('link[data-theme]')?.getAttribute('data-theme');
    let baseTheme = getStandardTheme(basicSettings);
    switch(themeName) {
    case 'dark':
      baseTheme = getDarkTheme(baseTheme);
      break;
    case 'high_contrast':
      baseTheme = getHightContrastTheme(baseTheme);
      break;
    }
    return getFinalTheme(baseTheme);
  }, []);
  return (
    <ThemeProvider theme={theme}>
      {props.children}
    </ThemeProvider>
  );
}

Theme.propTypes = {
  children: CustomPropTypes.children,
};

export const commonTableStyles = makeStyles((theme)=>({
  table: {
    borderSpacing: 0,
    width: '100%',
    overflow: 'auto',
    backgroundColor: theme.otherVars.tableBg,
    border: '1px solid '+theme.otherVars.borderColor,
    '& tbody td, & thead th': {
      margin: 0,
      padding: theme.spacing(0.5),
      border: '1px solid '+theme.otherVars.borderColor,
      borderBottom: 'none',
      position: 'relative',
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap',
      userSelect: 'text',
      '&:first-of-type':{
        borderLeft: 'none',
      },
    },
    '& thead tr:first-of-type th': {
      borderTop: 'none',
    },
    '& tbody tr:last-of-type': {
      '&:hover td': {
        borderBottomColor: theme.palette.primary.main,
      },
      '& td': {
        borderBottomColor: theme.otherVars.borderColor,
      }
    },
    '& th': {
      fontWeight: theme.typography.fontWeightBold,
      padding: theme.spacing(1, 0.5),
      textAlign: 'left',
    },
    '& tbody > tr': {
      '&:hover': {
        backgroundColor: theme.palette.primary.light,
        '& td': {
          borderBottom: '1px solid '+theme.palette.primary.main,
          borderTop: '1px solid '+theme.palette.primary.main,
        },
        '&:last-of-type td': {
          borderBottomColor: theme.palette.primary.main,
        },
      },
    },
  },
  noBorder: {
    border: 0,
  },
  borderBottom: {
    '& tbody tr:last-of-type td': {
      borderBottom: '1px solid '+theme.otherVars.borderColor,
    },
  },
  noHover: {
    '& tbody > tr': {
      '&:hover': {
        backgroundColor: theme.otherVars.tableBg,
        '& td': {
          borderBottomColor: theme.otherVars.borderColor,
          borderTopColor: theme.otherVars.borderColor,
        },
        '&:last-of-type td': {
          borderBottomColor: theme.otherVars.borderColor,
        },
      },
    },
  }
}));
