-- ============================================
-- COMPREHENSIVE DATE/TIME FIX SCRIPT
-- Fixes all date and time format issues in OptionsFlow_monthly and options_flow tables
-- ============================================
-- This script:
-- 1. Identifies problematic date/time entries
-- 2. Normalizes CreatedDate to YYYY-MM-DD format
-- 3. Normalizes CreatedTime to HH:MM:SS AM/PM format (with consistent spacing)
-- 4. Normalizes ExpirationDate to YYYY-MM-DD format
-- 5. Fixes timestamp issues in options_flow table
-- ============================================

-- ============================================
-- STEP 1: ANALYSIS - Identify problematic entries
-- ============================================

-- Check CreatedDate formats
SELECT 
  'CreatedDate Analysis' as check_type,
  COUNT(*) FILTER (WHERE "CreatedDate"::text ~ '^\d{4}-\d{2}-\d{2}$') as valid_iso_date,
  COUNT(*) FILTER (WHERE "CreatedDate"::text ~ '^\d{1,2}/\d{1,2}/\d{2,4}$') as slash_format,
  COUNT(*) FILTER (WHERE "CreatedDate" IS NOT NULL AND "CreatedDate"::text !~ '^\d{4}-\d{2}-\d{2}$' AND "CreatedDate"::text !~ '^\d{1,2}/\d{1,2}/\d{2,4}$') as invalid_format,
  COUNT(*) FILTER (WHERE "CreatedDate" IS NULL) as null_dates
FROM "OptionsFlow_monthly";

-- Check CreatedTime formats
SELECT 
  'CreatedTime Analysis' as check_type,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}:\d{2}:\d{2}\s+[AP]M$') as valid_with_space,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}:\d{2}:\d{2}[AP]M$') as valid_no_space,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}:\d{2}\s+[AP]M$') as valid_minutes_only_space,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}:\d{2}[AP]M$') as valid_minutes_only_no_space,
  COUNT(*) FILTER (WHERE "CreatedTime" IS NOT NULL AND "CreatedTime"::text !~* '(AM|PM)') as no_ampm,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}\s*[AP]M$' AND "CreatedTime"::text !~ ':') as missing_colon,
  COUNT(*) FILTER (WHERE "CreatedTime" IS NULL) as null_times
FROM "OptionsFlow_monthly";

-- Check ExpirationDate formats
SELECT 
  'ExpirationDate Analysis' as check_type,
  COUNT(*) FILTER (WHERE "ExpirationDate"::text ~ '^\d{4}-\d{2}-\d{2}$') as valid_iso_date,
  COUNT(*) FILTER (WHERE "ExpirationDate"::text ~ '^\d{1,2}/\d{1,2}/\d{2,4}$') as slash_format,
  COUNT(*) FILTER (WHERE "ExpirationDate" IS NOT NULL AND "ExpirationDate"::text !~ '^\d{4}-\d{2}-\d{2}$' AND "ExpirationDate"::text !~ '^\d{1,2}/\d{1,2}/\d{2,4}$') as invalid_format,
  COUNT(*) FILTER (WHERE "ExpirationDate" IS NULL) as null_dates
FROM "OptionsFlow_monthly";

-- ============================================
-- STEP 2: FIX CreatedDate - Normalize to YYYY-MM-DD
-- ============================================

UPDATE "OptionsFlow_monthly"
SET "CreatedDate" = 
  CASE
    -- Already in YYYY-MM-DD format - keep as-is
    WHEN "CreatedDate"::text ~ '^\d{4}-\d{2}-\d{2}$' 
      THEN "CreatedDate"::text
    -- MM/DD/YYYY format - convert to YYYY-MM-DD
    WHEN "CreatedDate"::text ~ '^(\d{1,2})/(\d{1,2})/(\d{2,4})$'
      THEN 
        TO_CHAR(
          to_date("CreatedDate"::text, 'MM/DD/YYYY'),
          'YYYY-MM-DD'
        )
    -- M/D/YYYY format - convert to YYYY-MM-DD
    WHEN "CreatedDate"::text ~ '^(\d{1,2})/(\d{1,2})/(\d{4})$'
      THEN 
        TO_CHAR(
          to_date("CreatedDate"::text, 'MM/DD/YYYY'),
          'YYYY-MM-DD'
        )
    -- Try to parse as date and reformat
    ELSE 
      CASE 
        WHEN to_date("CreatedDate"::text, 'YYYY-MM-DD') IS NOT NULL
          THEN TO_CHAR(to_date("CreatedDate"::text, 'YYYY-MM-DD'), 'YYYY-MM-DD')
        WHEN to_date("CreatedDate"::text, 'MM/DD/YYYY') IS NOT NULL
          THEN TO_CHAR(to_date("CreatedDate"::text, 'MM/DD/YYYY'), 'YYYY-MM-DD')
        ELSE "CreatedDate"::text  -- Keep original if can't parse
      END
  END
WHERE "CreatedDate" IS NOT NULL
  AND "CreatedDate"::text !~ '^\d{4}-\d{2}-\d{2}$';  -- Only update if not already correct

-- ============================================
-- STEP 3: FIX CreatedTime - Normalize spacing and format
-- ============================================

UPDATE "OptionsFlow_monthly"
SET "CreatedTime" = 
  CASE
    -- Already properly formatted with space: "HH:MM:SS AM" or "H:MM:SS AM"
    WHEN "CreatedTime"::text ~ '^\d{1,2}:\d{2}:\d{2}\s+[AP]M$'
      THEN "CreatedTime"::text  -- Keep as-is
    
    -- Missing space before AM/PM: "HH:MM:SSAM" -> "HH:MM:SS AM"
    WHEN "CreatedTime"::text ~ '^(\d{1,2}:\d{2}:\d{2})([AP]M)$'
      THEN REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2}:\d{2}:\d{2})([AP]M)$', '\1 \2', 'i')
    
    -- Minutes only with space: "HH:MM AM" -> "HH:MM:00 AM"
    WHEN "CreatedTime"::text ~ '^(\d{1,2}:\d{2})\s+([AP]M)$'
      THEN REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2}:\d{2})\s+([AP]M)$', '\1:00 \2', 'i')
    
    -- Minutes only without space: "HH:MMAM" -> "HH:MM:00 AM"
    WHEN "CreatedTime"::text ~ '^(\d{1,2}:\d{2})([AP]M)$'
      THEN REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2}:\d{2})([AP]M)$', '\1:00 \2', 'i')
    
    -- Just hour with space: "H AM" or "HH AM" -> "H:00:00 AM" or "HH:00:00 AM"
    WHEN "CreatedTime"::text ~ '^(\d{1,2})\s+([AP]M)$'
      THEN LPAD(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})\s+([AP]M)$', '\1', 'i'), 2, '0') || ':00:00 ' || 
           UPPER(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})\s+([AP]M)$', '\2', 'i'))
    
    -- Just hour without space: "HAM" or "HHAM" -> "H:00:00 AM" or "HH:00:00 AM"
    WHEN "CreatedTime"::text ~ '^(\d{1,2})([AP]M)$'
      THEN LPAD(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})([AP]M)$', '\1', 'i'), 2, '0') || ':00:00 ' || 
           UPPER(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})([AP]M)$', '\2', 'i'))
    
    -- Single digit hour with colon: ":MM AM" -> "H:MM:00 AM" (default to 9 AM or 1 PM)
    WHEN "CreatedTime"::text ~ '^:(\d{1,2})\s+([AP]M)$'
      THEN 
        CASE 
          WHEN UPPER(REGEXP_REPLACE("CreatedTime"::text, '^:(\d{1,2})\s+([AP]M)$', '\2', 'i')) = 'AM'
            THEN '9:' || LPAD(REGEXP_REPLACE("CreatedTime"::text, '^:(\d{1,2})\s+([AP]M)$', '\1', 'i'), 2, '0') || ':00 AM'
          ELSE '1:' || LPAD(REGEXP_REPLACE("CreatedTime"::text, '^:(\d{1,2})\s+([AP]M)$', '\1', 'i'), 2, '0') || ':00 PM'
        END
    
    -- Missing colon, just number and AM/PM (e.g., "34AM", "12PM")
    -- If > 12, assume it's minutes; otherwise could be hour or minute
    WHEN "CreatedTime"::text ~ '^(\d{2})([AP]M)$' AND (REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})([AP]M)$', '\1', 'i'))::int > 12
      THEN 
        CASE 
          WHEN UPPER(REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})([AP]M)$', '\2', 'i')) = 'AM'
            THEN '9:' || REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})([AP]M)$', '\1', 'i') || ':00 AM'
          ELSE '1:' || REGEXP_REPLACE("CreatedTime"::text, '^(\d{2})([AP]M)$', '\1', 'i') || ':00 PM'
        END
    
    -- Single or double digit <= 12 with AM/PM - ambiguous, default to hour
    WHEN "CreatedTime"::text ~ '^(\d{1,2})([AP]M)$' AND (REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})([AP]M)$', '\1', 'i'))::int <= 12
      THEN LPAD(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})([AP]M)$', '\1', 'i'), 2, '0') || ':00:00 ' || 
           UPPER(REGEXP_REPLACE("CreatedTime"::text, '^(\d{1,2})([AP]M)$', '\2', 'i'))
    
    -- Keep as-is if doesn't match any pattern
    ELSE "CreatedTime"::text
  END
WHERE "CreatedTime" IS NOT NULL
  AND (
    -- Update if missing space before AM/PM
    "CreatedTime"::text ~ '^\d{1,2}:\d{2}(:[0-9]{2})?[AP]M$'
    -- Or if missing colon or seconds
    OR ("CreatedTime"::text ~ '^\d{1,2}\s*[AP]M$' AND "CreatedTime"::text !~ ':')
    OR "CreatedTime"::text ~ '^:\d{1,2}\s*[AP]M$'
    OR ("CreatedTime"::text ~ '^\d{1,2}:\d{2}\s*[AP]M$' AND "CreatedTime"::text !~ ':\d{2}\s*[AP]M$')
  );

-- ============================================
-- STEP 4: FIX ExpirationDate - Normalize to YYYY-MM-DD
-- ============================================

UPDATE "OptionsFlow_monthly"
SET "ExpirationDate" = 
  CASE
    -- Already in YYYY-MM-DD format - keep as-is
    WHEN "ExpirationDate"::text ~ '^\d{4}-\d{2}-\d{2}$' 
      THEN "ExpirationDate"::text
    -- MM/DD/YYYY format - convert to YYYY-MM-DD
    WHEN "ExpirationDate"::text ~ '^(\d{1,2})/(\d{1,2})/(\d{2,4})$'
      THEN 
        TO_CHAR(
          to_date("ExpirationDate"::text, 'MM/DD/YYYY'),
          'YYYY-MM-DD'
        )
    -- Try to parse as date and reformat
    ELSE 
      CASE 
        WHEN to_date("ExpirationDate"::text, 'YYYY-MM-DD') IS NOT NULL
          THEN TO_CHAR(to_date("ExpirationDate"::text, 'YYYY-MM-DD'), 'YYYY-MM-DD')
        WHEN to_date("ExpirationDate"::text, 'MM/DD/YYYY') IS NOT NULL
          THEN TO_CHAR(to_date("ExpirationDate"::text, 'MM/DD/YYYY'), 'YYYY-MM-DD')
        ELSE "ExpirationDate"::text  -- Keep original if can't parse
      END
  END
WHERE "ExpirationDate" IS NOT NULL
  AND "ExpirationDate"::text !~ '^\d{4}-\d{2}-\d{2}$';  -- Only update if not already correct

-- ============================================
-- STEP 5: FIX options_flow table timestamps (if they exist)
-- ============================================

-- Fix expiration dates that might be NULL or invalid
UPDATE options_flow
SET expiration = NULL
WHERE expiration IS NOT NULL
  AND (expiration < '1970-01-01'::timestamp OR expiration > '2100-01-01'::timestamp);

-- Fix created_at dates that might be invalid
UPDATE options_flow
SET created_at = NOW()
WHERE created_at IS NOT NULL
  AND (created_at < '1970-01-01'::timestamp OR created_at > '2100-01-01'::timestamp);

-- ============================================
-- STEP 6: VERIFICATION - Check results
-- ============================================

-- Verify CreatedDate fixes
SELECT 
  'CreatedDate Verification' as check_type,
  COUNT(*) FILTER (WHERE "CreatedDate"::text ~ '^\d{4}-\d{2}-\d{2}$') as valid_format,
  COUNT(*) FILTER (WHERE "CreatedDate" IS NOT NULL AND "CreatedDate"::text !~ '^\d{4}-\d{2}-\d{2}$') as still_invalid,
  COUNT(*) FILTER (WHERE "CreatedDate" IS NULL) as null_count
FROM "OptionsFlow_monthly";

-- Verify CreatedTime fixes
SELECT 
  'CreatedTime Verification' as check_type,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}:\d{2}:\d{2}\s+[AP]M$') as valid_format,
  COUNT(*) FILTER (WHERE "CreatedTime"::text ~ '^\d{1,2}:\d{2}\s+[AP]M$') as minutes_only_valid,
  COUNT(*) FILTER (WHERE "CreatedTime" IS NOT NULL AND "CreatedTime"::text !~ '^\d{1,2}:\d{2}(:\d{2})?\s+[AP]M$') as still_invalid,
  COUNT(*) FILTER (WHERE "CreatedTime" IS NULL) as null_count
FROM "OptionsFlow_monthly";

-- Verify ExpirationDate fixes
SELECT 
  'ExpirationDate Verification' as check_type,
  COUNT(*) FILTER (WHERE "ExpirationDate"::text ~ '^\d{4}-\d{2}-\d{2}$') as valid_format,
  COUNT(*) FILTER (WHERE "ExpirationDate" IS NOT NULL AND "ExpirationDate"::text !~ '^\d{4}-\d{2}-\d{2}$') as still_invalid,
  COUNT(*) FILTER (WHERE "ExpirationDate" IS NULL) as null_count
FROM "OptionsFlow_monthly";

-- Show sample of fixed entries
SELECT 
  "CreatedDate",
  "CreatedTime",
  "ExpirationDate",
  "Symbol",
  COUNT(*) as count
FROM "OptionsFlow_monthly"
WHERE "CreatedDate"::text ~ '^\d{4}-\d{2}-\d{2}$'
  AND ("CreatedTime"::text ~ '^\d{1,2}:\d{2}(:\d{2})?\s+[AP]M$' OR "CreatedTime" IS NULL)
GROUP BY "CreatedDate", "CreatedTime", "ExpirationDate", "Symbol"
ORDER BY "CreatedDate" DESC, "CreatedTime" DESC
LIMIT 20;

-- ============================================
-- SUMMARY
-- ============================================
SELECT 
  '✅ Date/Time Fix Complete' as status,
  'Run the verification queries above to check results' as next_step;

