import {
  createParser,
  parseAsArrayOf,
  parseAsBoolean,
  parseAsInteger,
  parseAsString,
  parseAsStringLiteral,
  parseAsTimestamp,
} from 'nuqs'

import {
  ARRAY_DELIMITER,
  LEVELS,
  RANGE_DELIMITER,
  SLIDER_DELIMITER,
  SORT_DELIMITER,
} from '@/components/ui/DataTable/DataTable.constants'

export const REGIONS = ['ams', 'fra', 'gru', 'hkg', 'iad', 'syd'] as const
export const METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'] as const
export const LOG_TYPES = ['postgres', 'postgrest', 'auth', 'storage', 'edge function'] as const
export const DEFAULT_LOG_TYPES = ['postgres', 'postgrest'] as const

const parseAsSort = createParser({
  parse(queryValue: string) {
    const [id, desc] = queryValue.split(SORT_DELIMITER)
    if (!id && !desc) return null
    return { id, desc: desc === 'desc' }
  },
  serialize(value: { id: string; desc: boolean }) {
    return `${value.id}.${value.desc ? 'desc' : 'asc'}`
  },
})

export const SEARCH_PARAMS_PARSER = {
  // CUSTOM FILTERS
  level: parseAsArrayOf(parseAsStringLiteral(LEVELS), ARRAY_DELIMITER),
  log_type: parseAsArrayOf(parseAsString, ARRAY_DELIMITER),
  latency: parseAsArrayOf(parseAsInteger, SLIDER_DELIMITER),
  'timing.dns': parseAsArrayOf(parseAsInteger, SLIDER_DELIMITER),
  'timing.connection': parseAsArrayOf(parseAsInteger, SLIDER_DELIMITER),
  'timing.tls': parseAsArrayOf(parseAsInteger, SLIDER_DELIMITER),
  'timing.ttfb': parseAsArrayOf(parseAsInteger, SLIDER_DELIMITER),
  'timing.transfer': parseAsArrayOf(parseAsInteger, SLIDER_DELIMITER),
  status: parseAsArrayOf(parseAsString, ARRAY_DELIMITER),
  regions: parseAsArrayOf(parseAsStringLiteral(REGIONS), ARRAY_DELIMITER),
  method: parseAsArrayOf(parseAsStringLiteral(METHODS), ARRAY_DELIMITER),
  host: parseAsString,
  pathname: parseAsString,
  date: parseAsArrayOf(parseAsTimestamp, RANGE_DELIMITER),

  // REQUIRED FOR SORTING & PAGINATION
  sort: parseAsSort,
  size: parseAsInteger.withDefault(40),
  start: parseAsInteger.withDefault(0),

  // REQUIRED FOR INFINITE SCROLLING (Live Mode and Load More)
  direction: parseAsStringLiteral(['prev', 'next']).withDefault('next'),
  cursor: parseAsTimestamp.withDefault(new Date()),
  live: parseAsBoolean.withDefault(false),

  uuid: parseAsString,
  id: parseAsString,
}

const POSTGRES_STATUS_CODE_LABELS = {
  '00000': 'Successful Completion',
  '01000': 'Warning',
  '0100C': 'Dynamic Result Sets Returned',
  '01008': 'Implicit Zero Bit Padding',
  '01003': 'Null Value Eliminated In Set Function',
  '01007': 'Privilege Not Granted',
  '01006': 'Privilege Not Revoked',
  '01004': 'String Data Right Truncation',
  '01P01': 'Deprecated Feature',
  '02000': 'No Data',
  '02001': 'No Additional Dynamic Result Sets Returned',
  '03000': 'SQL Statement Not Yet Complete',
  '08000': 'Connection Exception',
  '08003': 'Connection Does Not Exist',
  '08006': 'Connection Failure',
  '08001': 'SQL Client Unable To Establish SQL Connection',
  '08004': 'SQL Server Rejected Establishment Of SQL Connection',
  '08007': 'Transaction Resolution Unknown',
  '08P01': 'Protocol Violation',
  '09000': 'Triggered Action Exception',
  '0A000': 'Feature Not Supported',
  '0B000': 'Invalid Transaction Initiation',
  '0F000': 'Locator Exception',
  '0F001': 'Invalid Locator Specification',
  '0L000': 'Invalid Grantor',
  '0LP01': 'Invalid Grant Operation',
  '0P000': 'Invalid Role Specification',
  '0Z000': 'Diagnostics Exception',
  '0Z002': 'Stacked Diagnostics Accessed Without Active Handler',
  '20000': 'Case Not Found',
  '21000': 'Cardinality Violation',
  '22000': 'Data Exception',
  '2202E': 'Array Subscript Error',
  '22021': 'Character Not In Repertoire',
  '22008': 'Datetime Field Overflow',
  '22012': 'Division By Zero',
  '22005': 'Error In Assignment',
  '2200B': 'Escape Character Conflict',
  '22022': 'Indicator Overflow',
  '22015': 'Interval Field Overflow',
  '2201E': 'Invalid Argument For Logarithm',
  '22014': 'Invalid Argument For Ntile Function',
  '22016': 'Invalid Argument For Nth Value Function',
  '2201F': 'Invalid Argument For Power Function',
  '2201G': 'Invalid Argument For Width Bucket Function',
  '22018': 'Invalid Character Value For Cast',
  '22007': 'Invalid Datetime Format',
  '22019': 'Invalid Escape Character',
  '2200D': 'Invalid Escape Octet',
  '22025': 'Invalid Escape Sequence',
  '22P06': 'Nonstandard Use Of Escape Character',
  '22010': 'Invalid Indicator Parameter Value',
  '22023': 'Invalid Parameter Value',
  '2201B': 'Invalid Regular Expression',
  '2201W': 'Invalid Row Count In Limit Clause',
  '2201X': 'Invalid Row Count In Result Offset Clause',
  '22009': 'Invalid Time Zone Displacement Value',
  '2200C': 'Invalid Use Of Escape Character',
  '2200G': 'Most Specific Type Mismatch',
  '22004': 'Null Value Not Allowed',
  '22002': 'Null Value No Indicator Parameter',
  '22003': 'Numeric Value Out Of Range',
  '22026': 'String Data Length Mismatch',
  '22001': 'String Data Right Truncation',
  '22011': 'Substring Error',
  '22027': 'Trim Error',
  '22024': 'Unterminated C String',
  '2200F': 'Zero Length Character String',
  '22P01': 'Floating Point Exception',
  '22P02': 'Invalid Text Representation',
  '22P03': 'Invalid Binary Representation',
  '22P04': 'Bad Copy File Format',
  '22P05': 'Untranslatable Character',
  '2200L': 'Not An XML Document',
  '2200M': 'Invalid XML Document',
  '2200N': 'Invalid XML Content',
  '2200S': 'Invalid XML Comment',
  '2200T': 'Invalid XML Processing Instruction',
  '23000': 'Integrity Constraint Violation',
  '23001': 'Restrict Violation',
  '23502': 'Not Null Violation',
  '23503': 'Foreign Key Violation',
  '23505': 'Unique Violation',
  '23514': 'Check Violation',
  '23P01': 'Exclusion Violation',
  '24000': 'Invalid Cursor State',
  '25000': 'Invalid Transaction State',
  '25001': 'Active SQL Transaction',
  '25002': 'Branch Transaction Already Active',
  '25008': 'Held Cursor Requires Same Isolation Level',
  '25003': 'Inappropriate Access Mode For Branch Transaction',
  '25004': 'Inappropriate Isolation Level For Branch Transaction',
  '25005': 'No Active SQL Transaction For Branch Transaction',
  '25006': 'Read Only SQL Transaction',
  '25007': 'Schema And Data Statement Mixing Not Supported',
  '25P01': 'No Active SQL Transaction',
  '25P02': 'In Failed SQL Transaction',
  '25P03': 'Idle In Transaction Session Timeout',
  '26000': 'Invalid SQL Statement Name',
  '27000': 'Triggered Data Change Violation',
  '28000': 'Invalid Authorization Specification',
  '28P01': 'Invalid Password',
  '2B000': 'Dependent Privilege Descriptors Still Exist',
  '2BP01': 'Dependent Objects Still Exist',
  '2D000': 'Invalid Transaction Termination',
  '2F000': 'SQL Routine Exception',
  '2F005': 'Function Executed No Return Statement',
  '2F002': 'Modifying SQL Data Not Permitted',
  '2F003': 'Prohibited SQL Statement Attempted',
  '2F004': 'Reading SQL Data Not Permitted',
  '34000': 'Invalid Cursor Name',
  '38000': 'External Routine Exception',
  '38001': 'Containing SQL Not Permitted',
  '38002': 'Modifying SQL Data Not Permitted',
  '38003': 'Prohibited SQL Statement Attempted',
  '38004': 'Reading SQL Data Not Permitted',
  '39000': 'External Routine Invocation Exception',
  '39001': 'Invalid SQLSTATE Returned',
  '39004': 'Null Value Not Allowed',
  '39P01': 'Trigger Protocol Violated',
  '39P02': 'SRF Protocol Violated',
  '39P03': 'Event Trigger Protocol Violated',
  '3B000': 'Savepoint Exception',
  '3B001': 'Invalid Savepoint Specification',
  '3D000': 'Invalid Catalog Name',
  '3F000': 'Invalid Schema Name',
  '40000': 'Transaction Rollback',
  '40002': 'Transaction Integrity Constraint Violation',
  '40001': 'Serialization Failure',
  '40003': 'Statement Completion Unknown',
  '40P01': 'Deadlock Detected',
  '42000': 'Syntax Error Or Access Rule Violation',
  '42601': 'Syntax Error',
  '42501': 'Insufficient Privilege',
  '42846': 'Cannot Coerce',
  '42803': 'Grouping Error',
  '42P20': 'Windowing Error',
  '42P19': 'Invalid Recursion',
  '42830': 'Invalid Foreign Key',
  '42602': 'Invalid Name',
  '42622': 'Name Too Long',
  '42939': 'Reserved Name',
  '42804': 'Datatype Mismatch',
  '42P18': 'Indeterminate Datatype',
  '42809': 'Wrong Object Type',
  '428C9': 'Generated Always',
  '42703': 'Undefined Column',
  '42883': 'Undefined Function',
  '42P01': 'Undefined Table',
  '42P02': 'Undefined Parameter',
  '42704': 'Undefined Object',
  '42701': 'Duplicate Column',
  '42P03': 'Duplicate Cursor',
  '42P04': 'Duplicate Database',
  '42723': 'Duplicate Function',
  '42P05': 'Duplicate Prepared Statement',
  '42P06': 'Duplicate Schema',
  '42P07': 'Duplicate Table',
  '42712': 'Duplicate Alias',
  '42710': 'Duplicate Object',
  '42702': 'Ambiguous Column',
  '42725': 'Ambiguous Function',
  '42P08': 'Ambiguous Parameter',
  '42P09': 'Ambiguous Alias',
  '42P10': 'Invalid Column Reference',
  '42611': 'Invalid Column Definition',
  '42P11': 'Invalid Cursor Definition',
  '42P12': 'Invalid Database Definition',
  '42P13': 'Invalid Function Definition',
  '42P14': 'Invalid Prepared Statement Definition',
  '42P15': 'Invalid Schema Definition',
  '42P16': 'Invalid Table Definition',
  '42P17': 'Invalid Object Definition',
  '44000': 'With Check Option Violation',
  '53000': 'Insufficient Resources',
  '53100': 'Disk Full',
  '53200': 'Out Of Memory',
  '53300': 'Too Many Connections',
  '53400': 'Configuration Limit Exceeded',
  '54000': 'Program Limit Exceeded',
  '54001': 'Statement Too Complex',
  '54011': 'Too Many Columns',
  '54023': 'Too Many Arguments',
  '55000': 'Object Not In Prerequisite State',
  '55006': 'Object In Use',
  '55P02': "Can't Change Runtime Param",
  '55P03': 'Lock Not Available',
  '55P04': 'Unsafe New Enum Value Usage',
  '57000': 'Operator Intervention',
  '57014': 'Query Canceled',
  '57P01': 'Admin Shutdown',
  '57P02': 'Crash Shutdown',
  '57P03': 'Cannot Connect Now',
  '57P04': 'Database Dropped',
  '58000': 'System Error',
  '58030': 'IO Error',
  '58P01': 'Undefined File',
  '58P02': 'Duplicate File',
  F0000: 'Config File Error',
  F0001: 'Lock File Exists',
  HV000: 'FDW Error',
  HV005: 'FDW Column Name Not Found',
  HV002: 'FDW Dynamic Parameter Value Needed',
  HV010: 'FDW Function Sequence Error',
  HV021: 'FDW Inconsistent Data',
  HV024: 'FDW Invalid Attribute Value',
  HV007: 'FDW Invalid Column Name',
  HV008: 'FDW Invalid Column Number',
  HV004: 'FDW Invalid Data Type',
  HV006: 'FDW Invalid Data Type Descriptors',
  HV091: 'FDW Invalid Handle',
  HV00B: 'FDW Invalid Option Index',
  HV00C: 'FDW Invalid Option Name',
  HV00D: 'FDW Invalid String Length Or Buffer Length',
  HV090: 'FDW Invalid String Format',
  HV00A: 'FDW Invalid Use Of Null Pointer',
  HV009: 'FDW Too Many Handles',
  HV014: 'FDW Out Of Memory',
  HV001: 'FDW Unsupported Function',
  P0000: 'PL/pgSQL Error',
  P0001: 'Raise Exception',
  P0002: 'No Data Found',
  P0003: 'Too Many Rows',
  P0004: 'Assert Failure',
  XX000: 'Internal Error',
  XX001: 'Data Corrupted',
  XX002: 'Index Corrupted',
}

const HTTP_STATUS_CODE_LABELS = {
  '100': 'Continue',
  '101': 'Switching Protocols',
  '102': 'Processing',
  '103': 'Early Hints',
  '200': 'OK',
  '201': 'Created',
  '202': 'Accepted',
  '203': 'Non-Authoritative Information',
  '204': 'No Content',
  '205': 'Reset Content',
  '206': 'Partial Content',
  '207': 'Multi-Status',
  '208': 'Already Reported',
  '226': 'IM Used',
  '300': 'Multiple Choices',
  '301': 'Moved Permanently',
  '302': 'Found',
  '303': 'See Other',
  '304': 'Not Modified',
  '305': 'Use Proxy',
  '307': 'Temporary Redirect',
  '308': 'Permanent Redirect',
  '400': 'Bad Request',
  '401': 'Unauthorized',
  '402': 'Payment Required',
  '403': 'Forbidden',
  '404': 'Not Found',
  '405': 'Method Not Allowed',
  '406': 'Not Acceptable',
  '407': 'Proxy Authentication Required',
  '408': 'Request Timeout',
  '409': 'Conflict',
  '410': 'Gone',
  '411': 'Length Required',
  '412': 'Precondition Failed',
  '413': 'Payload Too Large',
  '414': 'URI Too Long',
  '415': 'Unsupported Media Type',
  '416': 'Range Not Satisfiable',
  '417': 'Expectation Failed',
  '418': "I'm a teapot",
  '421': 'Misdirected Request',
  '422': 'Unprocessable Entity',
  '423': 'Locked',
  '424': 'Failed Dependency',
  '425': 'Too Early',
  '426': 'Upgrade Required',
  '428': 'Precondition Required',
  '429': 'Too Many Requests',
  '431': 'Request Header Fields Too Large',
  '451': 'Unavailable For Legal Reasons',
  '500': 'Internal Server Error',
  '501': 'Not Implemented',
  '502': 'Bad Gateway',
  '503': 'Service Unavailable',
  '504': 'Gateway Timeout',
  '505': 'HTTP Version Not Supported',
  '506': 'Variant Also Negotiates',
  '507': 'Insufficient Storage',
  '508': 'Loop Detected',
  '510': 'Not Extended',
  '511': 'Network Authentication Required',
}

export const STATUS_CODE_LABELS = {
  ...HTTP_STATUS_CODE_LABELS,
  ...POSTGRES_STATUS_CODE_LABELS,
}
