
    R-iH                        d Z ddlZddlmZ ddlmZmZmZ ddlmZm	Z	 	 ddl
mZmZ  ee      j                  dz  d	z  Zd
Zdee   fdZd:dededee   fdZdedefdZ	 d;dedededefdZ	 	 	 	 d<dededededee   f
dZ	 	 	 d=dededededef
dZd:dededee   fdZ	 	 d>dededededef
dZ	 	 	 	 d?dedededededefdZdededefd Zdefd!Ze d"k(  r e!d#        e!d$        e       Z" e!d%e"         e       Z# e!d& e$e#              e#D ]$  Z% e!d'e%d(    d)e%jM                  d*d+       d,       &  ed-d.      Z'e'r e!d/        e!d0e'd(    d)e'd1    d,        ed2d-d3      Z(e(jM                  d4      r) e!d5        e!d6e(d7   d(            e!d8e(d9    d,       yyy# e$ r ddl
mZmZ Y w xY w)@a  
British Gas Tariff API

Provides functions to read cached British Gas tariff data
for use in the main bill analyser application.

Usage:
    from scraper.british_gas_api import get_british_gas_tariffs, find_best_tariff

    # Get all tariffs for a region
    tariffs = get_british_gas_tariffs(postcode="HP20 1HP")

    # Find best matching tariff
    best = find_best_tariff(
        postcode="HP20 1HP",
        annual_electricity_kwh=2900,
        annual_gas_kwh=12000
    )
    N)Path)OptionalListDict)datetime	timedelta   )get_dno_for_postcodefind_matching_regionoutputzbritish-gas-tariffs.json   returnc                     t         j                         sy	 t        t         d      5 } t        j                  |       }ddd       j                  d      }|r[t        j                  |j                  dd            }t        j                  |j                        |z
  }|t        t              kD  ry|S # 1 sw Y   yxY w# t        $ r Y yw xY w)z
    Load cached British Gas tariff data.

    Returns:
        Dictionary with tariff data, or None if not available/stale
    Nr
scraped_atZ+00:00hours)TARIFF_FILEexistsopenjsonloadgetr   fromisoformatreplacenowtzinfor   CACHE_MAX_AGE_HOURS	Exception)fdatar   scraped_timeages        C:\Users\anton\Downloads\bill-analyser-claude-british-gas-frontend-01RLVAGZMevUtuaq9YdNNJYA(3)\bill-analyser-claude-british-gas-frontend-01RLVAGZMevUtuaq9YdNNJYA\scraper\british_gas_api.pyget_cached_datar'   &   s     +s# 	 q99Q<D	  XXl+
#11*2D2DS(2STL,,|223lBCY%899	  	   s.   C B5A5C 3C 5B>:C 	CCpostcoderegionc                 @   t               }|sg S |j                  dg       }| s5|s3|D ],  }|j                  d      s|j                  d      s'|d   c S  g S | rt        |       }|j                  d      }|r}|D cg c]%  }|j                  d      s|j                  d      ' }}t        | |      }|D ]<  }|j                  d      s|j                  d      |k(  s*|j                  dg       c S  |rq|D ]l  }|j                  d      s|j                  dd      j	                         }	|j	                         |	v s|	|j	                         v sZ|j                  dg       c S  |D ],  }|j                  d      s|j                  d      s'|d   c S  g S c c}w )a  
    Get British Gas tariffs, optionally filtered by postcode or region.

    Uses DNO lookup to accurately match postcodes to their electricity
    distribution region, ensuring users see correct regional pricing.

    Args:
        postcode: UK postcode to find regional tariffs
        region: Region name (alternative to postcode)

    Returns:
        List of tariff dictionaries for the matched region
    regionssuccesstariffsr)    r'   r   r
   r   lower)
r(   r)   r#   r+   r   dno_infotarget_regionavailable_regionsmatched_regionr_regions
             r&   get_british_gas_tariffsr6   A   s    D	hhy"%G F 	$AuuYAEE)$4|#	$ 	 '1 X.:A VQQUU9EUx V V1(<MNN  055#h>(I55B//0
  	,A55#uuXr*002H||~)X-GuuY++	,   55i 0Y<  I- !Ws   <FFc                    t        |       }|j                  d      }t               }g }d}d}|r|j                  dg       }|D ]M  }|j                  d      s|j                  d      |k(  s*|j                  dg       }|j                  d      } n |sQ|D ]L  }|j                  d      s|j                  d      s'|j                  dg       }|j                  d      }d} n | |j                  d      |j                  d	      |j                  d      |j                  d
      d|t        |      |||rddS ddS )z
    Get British Gas tariffs with detailed region matching info.

    Args:
        postcode: UK postcode

    Returns:
        Dictionary with tariffs and region matching details
    r)   FNr+   r,   r-   Tdno_codedno_namepostcode_prefix)codenamer)   r:   z+Using national tariffs from fallback region)r(   dnor-   tariff_countusing_fallbackactual_regionnote)r
   r   r'   len)	r(   r1   r2   r#   r-   r?   r@   r+   r   s	            r&   get_tariffs_with_region_inforC   |   sR    $H-HLL*M DGNM((9b)  	AuuYAEE(O}$D%%	2. !h		  55#i(8eeIr2G$%EE(OM%)N LL,LL,ll8,'||,=>	
 G(&AO=  VZ     tariffannual_electricity_kwhannual_gas_kwhc                 j   | j                  di       }| j                  di       }|j                  dd      xs d}|j                  dd      xs d}||z  dz  d|z  dz  z   }d}|dkD  r=|j                  dd      xs d}	|j                  dd      xs d}
||	z  dz  d|
z  dz  z   }t        ||z   d      S )	a3  
    Calculate annual cost for a tariff based on usage.

    Args:
        tariff: Tariff dictionary with rates
        annual_electricity_kwh: Annual electricity usage in kWh
        annual_gas_kwh: Annual gas usage in kWh (0 for electricity only)

    Returns:
        Estimated annual cost in pounds
    electricitygasunit_rate_pencer   standing_charge_penced   m     r   round)rE   rF   rG   elecrJ   elec_unit_rateelec_standing	elec_costgas_costgas_unit_rategas_standings              r&   calculate_annual_costrY      s      ::mR(D
**UB
C XX/38qNHH4a8=AM'.83>3CVY\C\]I H 115:ww6:?a"]2S8S<=ORU=UVX%q))rD   .  tariff_typec                 $   t        |       }|sy|rA|D cg c]6  }|j                  dd      j                         |j                         k(  s5|8 }}|syd}t        d      }|D ]#  }t	        |||      }	|	|k  s|	}i ||	||dd}% |S c c}w )a  
    Find the best (cheapest) British Gas tariff for given usage.

    Args:
        postcode: Postcode to find regional tariffs
        annual_electricity_kwh: Annual electricity usage (default: UK average)
        annual_gas_kwh: Annual gas usage (default: UK average, 0 for elec only)
        tariff_type: Filter by type ("Fixed", "Variable", etc.)

    Returns:
        Best tariff with calculated cost, or None if no tariffs available
    r(   Ntyper.   inf)electricity_kwhgas_kwh)calculated_annual_costusage)r6   r   r0   floatrY   )
r(   rF   rG   r[   r-   tbest	best_costrE   costs
             r&   find_best_tariffri      s    $ &x8G %Zvr):)@)@)BkFWFWFY)Y1ZZ DeI $V-C^T)I*.'=-D	 K- [s   6BBcurrent_annual_costc                    t        |      }|sdddS g }|D ]v  }t        |||      }| |z
  }|j                  |j                  d      |j                  d      |t	        |d      |dkD  |j                  d	      |j                  d
      d       x |j                  d        |r|d   nd}	d| |	||	r|	d   r|	d   dS ddS )aa  
    Compare current tariff cost against British Gas options.

    Args:
        current_annual_cost: Current annual energy cost in pounds
        postcode: Postcode for regional tariffs
        annual_electricity_kwh: Annual electricity usage
        annual_gas_kwh: Annual gas usage

    Returns:
        Comparison results with potential savings
    r]   FzABritish Gas tariff data not available. Run the scraper to update.	availablemessager<   r^   rO   r   rI   rJ   )r<   r^   annual_costsaving
is_cheaperrI   rJ   c                     | d   S )Nro    )xs    r&   <lambda>z!compare_tariffs.<locals>.<lambda>1  s    1]#3 rD   )keyNTrq   rp   )rm   current_costbest_tariffall_tariffspotential_saving)r6   rY   appendr   rQ   sort)
rj   r(   rF   rG   r-   comparisonsrE   rh   rp   rf   s
             r&   compare_tariffsr~     s   $ &x8GZ
 	

 K $V-C^T$t+JJv&JJv&FA& 1*!::m4::e$
 		 34(;q>dD +".2tL7IDN 
 PQ rD   c                    t               }|sy|j                  dg       }| rt        |       }|j                  d      }|r||D cg c]%  }|j                  d      s|j                  d      ' }}t        | |      }|D ];  }|j                  d      s|j                  d      |k(  s*|j                  d      c S  |rp|D ]k  }|j                  d      s|j                  dd      j	                         }	|j	                         |	v s|	|j	                         v sZ|j                  d      c S  |D ],  }|j                  d      s|j                  d      s'|d   c S  yc c}w )a  
    Get British Gas EV Power tariff for a region.

    The EV tariff has time-of-use pricing:
    - Peak rate: Standard daytime electricity rate
    - Off-peak rate: Cheaper overnight rate (12am-5am)

    Args:
        postcode: UK postcode to find regional EV tariff
        region: Region name (alternative to postcode)

    Returns:
        EV tariff dictionary with peak/off-peak rates, or None if not available
    Nr+   r)   r,   	ev_tariffr.   r/   )
r(   r)   r#   r+   r1   r2   r   r3   r4   r5   s
             r&   get_ev_tariffr   >  sR    Dhhy"%G '1 X.:A VQQUU9EUx V V1(<MNN .55#h>(I55--.
  	*A55#uuXr*002H||~)X-Guu[))	*  "55k 2[>!" + !Ws   E E r   off_peak_percentagec           
         | j                  di       }| j                  di       }||z  }|d|z
  z  }|j                  dd      xs d}|j                  dd      xs d}	|j                  dd      xs d}
||z  dz  }||	z  dz  }d	|
z  dz  }||z   |z   }d}|dkD  r=|j                  d
d      xs d}|j                  dd      xs d}||z  dz  d	|z  dz  z   }||z   }t        |d      t        |d      t        |d      t        |d      t        |d      t        |d      t        |d      d|t        |d      d|t        ||z  dz  ||	z  dz  z
  d      dS )a  
    Calculate annual cost for an EV tariff with peak/off-peak split.

    Args:
        ev_tariff: EV tariff dictionary with peak/off-peak rates
        annual_electricity_kwh: Total annual electricity usage in kWh
        annual_gas_kwh: Annual gas usage in kWh (0 for electricity only)
        off_peak_percentage: Fraction of electricity used during off-peak (0.0-1.0)
                            Default 0.5 assumes 50% overnight charging

    Returns:
        Dictionary with cost breakdown
    rI   rJ   r	   peak_unit_rate_pencer   off_peak_unit_rate_pencerL   rM   rN   rK   rO   )peak_kwh	peak_costoff_peak_kwhoff_peak_coststanding_charge_costtotal)kwhr   )ro   rI   rJ   r   savings_from_off_peakrP   )r   rF   rG   r   rR   rJ   r   r   	peak_rateoff_peak_raterT   r   r   elec_standing_costtotal_elec_costrV   rW   rX   
total_costs                      r&   calculate_ev_annual_costr   q  s   & ==+D
--r
"C *,??L%-@)@AH /38qIHH7;@qMHH4a8=AM 9$s*I =036M},s2-/2DDO H 115:ww6:?a"]2S8S<=ORU=UV 8+J Z+h*y!,!,2"=!4$)*<a$@?A.
 "8Q'
  3!&9(<s(BxR_G_beGe'fhi!j rD   c                    t        |      }|sdddS t        ||||      }|d   }| |z
  }d| |j                  dd      d	|t        |d
      |dkD  |j                  di       j                  d      |j                  di       j                  d      |j                  di       j                  d      |j                  di       j                  d      |j                  di       j                  d      d|d|dkD  r|ndt	        ||      dS )a  
    Compare current tariff cost against British Gas EV Power tariff.

    Useful for EV owners to see if switching to time-of-use pricing saves money.

    Args:
        current_annual_cost: Current annual energy cost in pounds
        postcode: Postcode for regional tariffs
        annual_electricity_kwh: Annual electricity usage
        annual_gas_kwh: Annual gas usage
        off_peak_percentage: Fraction of electricity used during off-peak hours

    Returns:
        Comparison results with potential savings
    r]   FzDBritish Gas EV tariff data not available. Run the scraper to update.rl   ro   Tr<   zEV Power TariffEVrO   r   rI   r   r   rL   rJ   rK   )electricity_peak_penceelectricity_off_peak_penceelectricity_standing_pencegas_unit_pencegas_standing_pence)r<   r^   ro   rp   rq   ratescost_breakdown)rm   rw   r   rz   recommendation)r   r   r   rQ   _get_ev_recommendation)	rj   r(   rF   rG   r   r   r   ev_costrp   s	            r&   compare_ev_tariffr     s0   , x0I]
 	

 .	N ]+G 7*F +MM&*;<"FA& 1**3--r*J*N*NOe*f.7mmM2.N.R.RSm.n.7mmM2.N.R.RSj.k"+--r":">">?P"Q&/mmE2&>&B&BCZ&[ -
 '-qjFa09LM' rD   rp   c                 ~    | dkD  rdt        |        dS | dkD  rdt        |        dS | dkD  ryd	t        |         d
S )z6Generate a plain English recommendation for EV tariff.rM   u   This could save you £z0/year. Great for EV owners who charge overnight.r   u   Small saving of £z>/year. Consider if you can shift more usage to off-peak hours.izaSimilar cost to your current tariff. Only worth switching if you can increase overnight charging.u   Would cost £zC/year more. Not recommended unless you can charge mostly overnight.)rQ   )rp   r   s     r&   r   r     sY    |'f6fgg	!#E&M?2pqq	#rufW~..qrrrD   c            
      6   t         j                         sdddS 	 t        t         d      5 } t        j                  |       }ddd       j                  d      }|rt        j                  |j                  dd            }t        j                  |j                        |z
  }d	|t        |j                         d
z  d      |t        t              k  t        |j                  dg             dS y# 1 sw Y   xY w# t         $ r}dd| dcY d}~S d}~ww xY w)zi
    Check how fresh the cached data is.

    Returns:
        Dictionary with freshness information
    Fz8No cached data. Run: python british_gas_scraper.py --allrl   r   Nr   r   r   Ti  r	   r   r+   )rm   r   	age_hoursis_freshregions_countzError reading cache: )r   r   r   r   r   r   r   r   r   r   r   rQ   total_secondsr   r    rB   r!   )r"   r#   r   r$   r%   es         r&   get_data_freshnessr     s    Q
 	


+s# 	 q99Q<D	  XXl+
#11*2D2DS(2STL,,|223lBC "("3#4#4#6#=qA)2E"FF!$TXXi%<!= 	 		  	   
.qc2
 	

s5   C= C1B.C= 1C:6C= =	DDDD__main__zBritish Gas Tariff APIz2==================================================z
Data freshness: z
Available tariffs: z  - r<   u   : £ro   zN/Az/yeari  )rF   rG   z/
Best tariff for 3000 kWh elec + 12000 kWh gas:z  rb   i  )rj   rF   rG   rm   u&   
Compared to £1800/year current cost:z  Best: rx   u     Potential saving: £rz   )NN)r   )NT  rZ   N)Nr   rZ   )r         ?)Nr   rZ   r   ))__doc__r   pathlibr   typingr   r   r   r   r   
dno_lookupr
   r   ImportError__file__parentr   r    dictr'   strr6   rC   rd   rY   ri   r~   r   r   r   r   r   __name__print	freshnessr-   rB   re   r   rf   
comparisonrs   rD   r&   <module>r      sX  (   ' ' (FF 8n##h.1KK $ 68c 8# 8d 8v33 34 3r  * *! *  * 	 *H $(!	//!/ / 	/
 d^/h $(!	444 "4 	4
 
4n0C 0 0x~ 0l !$	>>!> > 	>
 
>F $(!!$<<< "< 	<
 < 
<~	s5 	su 	s 	s!
D !
J z	
"#	(O #$I	yk
*+ &'G	!#g,
01 HQvYKtAEE-$?#@FGH 4ND@B4<.T*B%C$DEJK ! #J
 ~~k"79M26:;<=&z2D'E&FeLM #7 K  FEEFs   F3 3GG